blob: 626b6d1a32241e92f7b79c40115987f0c922cdce [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.com1d6aff22012-11-28 19:30:42 +000025
26#include "libEGL/Config.h"
27#include "libEGL/Display.h"
28
29namespace rx
30{
daniel@transgaming.com65e65372012-11-28 19:33:50 +000031static const DXGI_FORMAT RenderTargetFormats[] =
32 {
33 DXGI_FORMAT_R8G8B8A8_UNORM
34 };
35
36static const DXGI_FORMAT DepthStencilFormats[] =
37 {
38 DXGI_FORMAT_D24_UNORM_S8_UINT
39 };
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000040
41Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
42{
43 mD3d11Module = NULL;
44 mDxgiModule = NULL;
45
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +000046 mDeviceLost = false;
47
daniel@transgaming.com25072f62012-11-28 19:31:32 +000048 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000049 mDeviceContext = NULL;
daniel@transgaming.com65e65372012-11-28 19:33:50 +000050 mDxgiAdapter = NULL;
51 mDxgiFactory = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000052}
53
54Renderer11::~Renderer11()
55{
56 releaseDeviceResources();
57
daniel@transgaming.com65e65372012-11-28 19:33:50 +000058 if (mDxgiFactory)
59 {
60 mDxgiFactory->Release();
61 mDxgiFactory = NULL;
62 }
63
64 if (mDxgiAdapter)
65 {
66 mDxgiAdapter->Release();
67 mDxgiAdapter = NULL;
68 }
69
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000070 if (mDeviceContext)
71 {
72 mDeviceContext->Release();
73 mDeviceContext = NULL;
74 }
75
daniel@transgaming.com25072f62012-11-28 19:31:32 +000076 if (mDevice)
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000077 {
daniel@transgaming.com25072f62012-11-28 19:31:32 +000078 mDevice->Release();
79 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000080 }
81
82 if (mD3d11Module)
83 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000084 FreeLibrary(mD3d11Module);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000085 mD3d11Module = NULL;
86 }
87
88 if (mDxgiModule)
89 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000090 FreeLibrary(mDxgiModule);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000091 mDxgiModule = NULL;
92 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000093}
94
daniel@transgaming.comb64ed282012-11-28 20:54:02 +000095Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
96{
97 ASSERT(dynamic_cast<rx::Renderer11*>(renderer) != NULL);
98 return static_cast<rx::Renderer11*>(renderer);
99}
100
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000101EGLint Renderer11::initialize()
102{
daniel@transgaming.com25e16af2012-11-28 21:05:57 +0000103 if (!initializeCompiler())
104 {
105 return EGL_NOT_INITIALIZED;
106 }
107
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000108 mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
109 mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000110
111 if (mD3d11Module == NULL || mDxgiModule == NULL)
112 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000113 ERR("Could not load D3D11 or DXGI library - aborting!\n");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000114 return EGL_NOT_INITIALIZED;
115 }
116
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000117 PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000118
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000119 if (D3D11CreateDevice == NULL)
120 {
121 ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
122 return EGL_NOT_INITIALIZED;
123 }
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000124
125 D3D_FEATURE_LEVEL featureLevel[] =
126 {
127 D3D_FEATURE_LEVEL_11_0,
128 D3D_FEATURE_LEVEL_10_1,
129 D3D_FEATURE_LEVEL_10_0,
130 };
131
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000132 HRESULT result = D3D11CreateDevice(NULL,
133 D3D_DRIVER_TYPE_HARDWARE,
134 NULL,
daniel@transgaming.coma60160b2012-11-28 19:41:15 +0000135 #if defined(_DEBUG)
136 D3D11_CREATE_DEVICE_DEBUG,
137 #else
138 0,
139 #endif
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000140 featureLevel,
141 sizeof(featureLevel)/sizeof(featureLevel[0]),
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000142 D3D11_SDK_VERSION,
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000143 &mDevice,
144 &mFeatureLevel,
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000145 &mDeviceContext);
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000146
147 if (!mDevice || FAILED(result))
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000148 {
149 ERR("Could not create D3D11 device - aborting!\n");
150 return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer
151 }
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000152
153 IDXGIDevice *dxgiDevice = NULL;
154 result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
155
156 if (FAILED(result))
157 {
158 ERR("Could not query DXGI device - aborting!\n");
159 return EGL_NOT_INITIALIZED;
160 }
161
162 result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
163
164 if (FAILED(result))
165 {
166 ERR("Could not retrieve DXGI adapter - aborting!\n");
167 return EGL_NOT_INITIALIZED;
168 }
169
170 dxgiDevice->Release();
171
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000172 mDxgiAdapter->GetDesc(&mAdapterDescription);
173 memset(mDescription, 0, sizeof(mDescription));
174 wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
175
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000176 result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
177
178 if (!mDxgiFactory || FAILED(result))
179 {
180 ERR("Could not create DXGI factory - aborting!\n");
181 return EGL_NOT_INITIALIZED;
182 }
183
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000184 initializeDevice();
185
186 return EGL_SUCCESS;
187}
188
189// do any one-time device initialization
190// NOTE: this is also needed after a device lost/reset
191// to reset the scene status and ensure the default states are reset.
192void Renderer11::initializeDevice()
193{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000194 mStateCache.initialize(mDevice);
195
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000196 markAllStateDirty();
197
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000198 // Permanent non-default states
199 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000200 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000201}
202
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000203int Renderer11::generateConfigs(ConfigDesc **configDescList)
204{
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000205 unsigned int numRenderFormats = sizeof(RenderTargetFormats) / sizeof(RenderTargetFormats[0]);
206 unsigned int numDepthFormats = sizeof(DepthStencilFormats) / sizeof(DepthStencilFormats[0]);
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000207 (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
208 int numConfigs = 0;
209
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000210 for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000211 {
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000212 for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000213 {
214 DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
215
216 UINT formatSupport = 0;
217 HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
218
219 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
220 {
221 DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
222
223 UINT formatSupport = 0;
224 HRESULT result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport);
225
226 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL))
227 {
228 ConfigDesc newConfig;
229 newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat);
230 newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat);
231 newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
232 newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast
233
234 (*configDescList)[numConfigs++] = newConfig;
235 }
236 }
237 }
238 }
239
240 return numConfigs;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000241}
242
243void Renderer11::deleteConfigs(ConfigDesc *configDescList)
244{
245 delete [] (configDescList);
246}
247
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000248void Renderer11::sync(bool block)
249{
250 // TODO
251 UNIMPLEMENTED();
252}
253
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000254SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
255{
daniel@transgaming.coma60160b2012-11-28 19:41:15 +0000256 return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000257}
258
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000259void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
260{
261 // TODO
262 UNIMPLEMENTED();
263}
264
265void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
266{
267 // TODO
268 UNIMPLEMENTED();
269}
270
daniel@transgaming.com237bc7e2012-11-28 21:01:06 +0000271void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000272{
daniel@transgaming.com237bc7e2012-11-28 21:01:06 +0000273 if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000274 {
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000275 ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled,
276 mCurDepthSize);
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000277 if (!dxRasterState)
278 {
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000279 ERR("NULL blend state returned by RenderStateCache::getRasterizerState, setting the default"
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000280 "rasterizer state.");
281 }
282
283 mDeviceContext->RSSetState(dxRasterState);
284
285 if (dxRasterState)
286 {
287 dxRasterState->Release();
288 }
289 mCurRasterState = rasterState;
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000290 }
291
292 mForceSetRasterState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000293}
294
295void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
296 unsigned int sampleMask)
297{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000298 if (mForceSetBlendState ||
299 memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 ||
300 memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0 ||
301 sampleMask != mCurSampleMask)
302 {
303 ID3D11BlendState *dxBlendState = mStateCache.getBlendState(blendState);
304 if (!dxBlendState)
305 {
306 ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default "
307 "blend state.");
308 }
309
310 const float blendColors[] = { blendColor.red, blendColor.green, blendColor.blue, blendColor.alpha };
311 mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
312
313 if (dxBlendState)
314 {
315 dxBlendState->Release();
316 }
317 mCurBlendState = blendState;
318 mCurBlendColor = blendColor;
319 mCurSampleMask = sampleMask;
320 }
321
322 mForceSetBlendState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000323}
324
daniel@transgaming.com08c331d2012-11-28 19:38:39 +0000325void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
daniel@transgaming.com3a0ef482012-11-28 21:01:20 +0000326 int stencilBackRef, bool frontFaceCCW)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000327{
daniel@transgaming.com5503fd02012-11-28 19:38:57 +0000328 if (mForceSetDepthStencilState ||
329 memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
330 stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
331 {
332 if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
333 stencilRef != stencilBackRef ||
334 depthStencilState.stencilMask != depthStencilState.stencilBackMask)
335 {
336 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are "
337 "invalid under WebGL.");
338 return error(GL_INVALID_OPERATION);
339 }
340
341 ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState);
342 if (!dxDepthStencilState)
343 {
344 ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, "
345 "setting the default depth stencil state.");
346 }
347
348 mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, static_cast<UINT>(stencilRef));
349
350 if (dxDepthStencilState)
351 {
352 dxDepthStencilState->Release();
353 }
354 mCurDepthStencilState = depthStencilState;
355 mCurStencilRef = stencilRef;
356 mCurStencilBackRef = stencilBackRef;
357 }
358
359 mForceSetDepthStencilState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000360}
361
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000362void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000363{
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000364 if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
365 enabled != mScissorEnabled)
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000366 {
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000367 if (enabled)
368 {
369 D3D11_RECT rect;
370 rect.left = gl::clamp(scissor.x, 0, static_cast<int>(mRenderTargetDesc.width));
371 rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetDesc.height));
372 rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetDesc.width));
373 rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(mRenderTargetDesc.height));
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000374
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000375 mDeviceContext->RSSetScissorRects(1, &rect);
376 }
377
378 if (enabled != mScissorEnabled)
379 {
380 mForceSetRasterState = true;
381 }
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000382
383 mCurScissor = scissor;
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000384 mScissorEnabled = enabled;
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000385 }
386
387 mForceSetScissor = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000388}
389
daniel@transgaming.com12985182012-12-20 20:56:31 +0000390bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
391 bool ignoreViewport, gl::ProgramBinary *currentProgram, bool forceSetUniforms)
daniel@transgaming.com83e80ee2012-11-28 19:40:53 +0000392{
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000393 gl::Rectangle actualViewport = viewport;
394 float actualZNear = gl::clamp01(zNear);
395 float actualZFar = gl::clamp01(zFar);
396 if (ignoreViewport)
397 {
398 actualViewport.x = 0;
399 actualViewport.y = 0;
400 actualViewport.width = mRenderTargetDesc.width;
401 actualViewport.height = mRenderTargetDesc.height;
402 actualZNear = 0.0f;
403 actualZFar = 1.0f;
404 }
daniel@transgaming.com53670042012-11-28 20:55:51 +0000405
406 D3D11_VIEWPORT dxViewport;
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000407 dxViewport.TopLeftX = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetDesc.width));
408 dxViewport.TopLeftY = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetDesc.height));
409 dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.TopLeftX));
410 dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.TopLeftY));
411 dxViewport.MinDepth = actualZNear;
412 dxViewport.MaxDepth = actualZFar;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000413
414 if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
415 {
416 return false; // Nothing to render
417 }
418
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000419 bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
420 actualZNear != mCurNear || actualZFar != mCurFar;
421
daniel@transgaming.com53670042012-11-28 20:55:51 +0000422 if (viewportChanged)
423 {
424 mDeviceContext->RSSetViewports(1, &dxViewport);
425
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000426 mCurViewport = actualViewport;
427 mCurNear = actualZNear;
428 mCurFar = actualZFar;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000429 }
430
431 if (currentProgram && (viewportChanged || forceSetUniforms))
432 {
daniel@transgaming.com88853c52012-12-20 20:56:40 +0000433 currentProgram->applyDxHalfPixelSize(0.0f, 0.0f);
daniel@transgaming.com53670042012-11-28 20:55:51 +0000434
435 // These values are used for computing gl_FragCoord in Program::linkVaryings().
daniel@transgaming.com88853c52012-12-20 20:56:40 +0000436 currentProgram->applyDxCoord(actualViewport.width * 0.5f,
437 actualViewport.height * 0.5f,
438 actualViewport.x + (actualViewport.width * 0.5f),
439 actualViewport.y + (actualViewport.height * 0.5f));
daniel@transgaming.com53670042012-11-28 20:55:51 +0000440
daniel@transgaming.com12985182012-12-20 20:56:31 +0000441 GLfloat ccw = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f);
daniel@transgaming.com88853c52012-12-20 20:56:40 +0000442 currentProgram->applyDxDepthFront((actualZFar - actualZNear) * 0.5f, (actualZNear + actualZFar) * 0.5f, ccw);
daniel@transgaming.com53670042012-11-28 20:55:51 +0000443
daniel@transgaming.com88853c52012-12-20 20:56:40 +0000444 currentProgram->applyDxDepthRange(actualZNear, actualZFar, actualZFar - actualZNear);
daniel@transgaming.com53670042012-11-28 20:55:51 +0000445 }
446
447 mForceSetViewport = false;
daniel@transgaming.com83e80ee2012-11-28 19:40:53 +0000448 return true;
449}
450
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000451bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
452{
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000453 D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000454
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000455 switch (mode)
456 {
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000457 case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; break;
458 case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; break;
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000459 case GL_LINE_LOOP: UNIMPLEMENTED(); /* TODO */ break;
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000460 case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break;
461 case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break;
462 case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break;
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000463 case GL_TRIANGLE_FAN: UNIMPLEMENTED(); /* TODO */ break;
464 default:
465 return error(GL_INVALID_ENUM, false);
466 }
467
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000468 mDeviceContext->IASetPrimitiveTopology(primitiveTopology);
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000469
470 return count > 0;
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000471}
472
473bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000474{
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000475 // Get the color render buffer and serial
476 gl::Renderbuffer *renderbufferObject = NULL;
477 unsigned int renderTargetSerial = 0;
478 if (framebuffer->getColorbufferType() != GL_NONE)
479 {
480 renderbufferObject = framebuffer->getColorbuffer();
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000481
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000482 if (!renderbufferObject)
483 {
484 ERR("render target pointer unexpectedly null.");
daniel@transgaming.come9c71b42012-11-28 21:02:23 +0000485 return false;
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000486 }
487
488 renderTargetSerial = renderbufferObject->getSerial();
489 }
490
491 // Get the depth stencil render buffer and serials
492 gl::Renderbuffer *depthStencil = NULL;
493 unsigned int depthbufferSerial = 0;
494 unsigned int stencilbufferSerial = 0;
495 if (framebuffer->getDepthbufferType() != GL_NONE)
496 {
497 depthStencil = framebuffer->getDepthbuffer();
498 if (!depthStencil)
499 {
500 ERR("Depth stencil pointer unexpectedly null.");
501 return false;
502 }
503
504 depthbufferSerial = depthStencil->getSerial();
505 }
506 else if (framebuffer->getStencilbufferType() != GL_NONE)
507 {
508 depthStencil = framebuffer->getStencilbuffer();
509 if (!depthStencil)
510 {
511 ERR("Depth stencil pointer unexpectedly null.");
512 return false;
513 }
514
515 stencilbufferSerial = depthStencil->getSerial();
516 }
517
518 // Extract the render target dimensions and view
519 unsigned int renderTargetWidth = 0;
520 unsigned int renderTargetHeight = 0;
521 GLenum renderTargetFormat = 0;
522 ID3D11RenderTargetView* framebufferRTV = NULL;
523 if (renderbufferObject)
524 {
525 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
526 if (!renderTarget)
527 {
528 ERR("render target pointer unexpectedly null.");
529 return false;
530 }
531
532 framebufferRTV = renderTarget->getRenderTargetView();
533 if (!framebufferRTV)
534 {
535 ERR("render target view pointer unexpectedly null.");
536 return false;
537 }
538
539 renderTargetWidth = renderbufferObject->getWidth();
540 renderTargetHeight = renderbufferObject->getHeight();
541 renderTargetFormat = renderbufferObject->getActualFormat();
542 }
543
544 // Extract the depth stencil sizes and view
545 unsigned int depthSize = 0;
546 unsigned int stencilSize = 0;
547 ID3D11DepthStencilView* framebufferDSV = NULL;
548 if (depthStencil)
549 {
550 RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil());
551 if (!depthStencilRenderTarget)
552 {
553 ERR("render target pointer unexpectedly null.");
554 if (framebufferRTV)
555 {
556 framebufferRTV->Release();
557 }
558 return false;
559 }
560
561 framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
562 if (!framebufferDSV)
563 {
564 ERR("depth stencil view pointer unexpectedly null.");
565 if (framebufferRTV)
566 {
567 framebufferRTV->Release();
568 }
569 return false;
570 }
571
572 // If there is no render buffer, the width, height and format values come from
573 // the depth stencil
574 if (!renderbufferObject)
575 {
576 renderTargetWidth = depthStencil->getWidth();
577 renderTargetHeight = depthStencil->getHeight();
578 renderTargetFormat = depthStencil->getActualFormat();
579 }
580
581 depthSize = depthStencil->getDepthSize();
582 stencilSize = depthStencil->getStencilSize();
583 }
584
585 // Apply the render target and depth stencil
586 if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
587 renderTargetSerial != mAppliedRenderTargetSerial ||
588 depthbufferSerial != mAppliedDepthbufferSerial ||
589 stencilbufferSerial != mAppliedStencilbufferSerial)
590 {
591 mDeviceContext->OMSetRenderTargets(1, &framebufferRTV, framebufferDSV);
592
593 mRenderTargetDesc.width = renderTargetWidth;
594 mRenderTargetDesc.height = renderTargetHeight;
595 mRenderTargetDesc.format = renderTargetFormat;
596 mForceSetViewport = true; // TODO: It may not be required to clamp the viewport in D3D11
597 mForceSetScissor = true; // TODO: It may not be required to clamp the scissor in D3D11
598
599 if (!mDepthStencilInitialized || depthSize != mCurDepthSize)
600 {
601 mCurDepthSize = depthSize;
602 mForceSetRasterState = true;
603 }
604
605 mCurStencilSize = stencilSize;
606
607 mAppliedRenderTargetSerial = renderTargetSerial;
608 mAppliedDepthbufferSerial = depthbufferSerial;
609 mAppliedStencilbufferSerial = stencilbufferSerial;
610 mRenderTargetDescInitialized = true;
611 mDepthStencilInitialized = true;
612 }
613
614 if (framebufferRTV)
615 {
616 framebufferRTV->Release();
617 }
618 if (framebufferDSV)
619 {
620 framebufferDSV->Release();
621 }
daniel@transgaming.comae39ee22012-11-28 19:42:02 +0000622
623 return true;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000624}
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000625
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000626GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
daniel@transgaming.comdef9f0f2012-11-28 20:53:20 +0000627{
daniel@transgaming.com18adad02012-11-28 21:04:03 +0000628 // TODO: Create/update vertex buffers for arbitrary GL attributes
629 ASSERT(vertexAttributes[0].mBoundBuffer.get() == 0); // UNIMPLEMENTED();
630
631 UINT stride = vertexAttributes[0].mStride != 0 ? vertexAttributes[0].mStride : vertexAttributes[0].typeSize();
632 UINT size = stride * count;
633
634 D3D11_BUFFER_DESC vertexBufferDescription = {0};
635 vertexBufferDescription.ByteWidth = size;
636 vertexBufferDescription.Usage = D3D11_USAGE_DYNAMIC;
637 vertexBufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;
638 vertexBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
639 vertexBufferDescription.MiscFlags = 0;
640 vertexBufferDescription.StructureByteStride = 0;
641
642 ID3D11Buffer *vertexBuffer = NULL;
643 HRESULT result = mDevice->CreateBuffer(&vertexBufferDescription, NULL, &vertexBuffer);
644 ASSERT(SUCCEEDED(result));
645
646 D3D11_MAPPED_SUBRESOURCE map;
647 result = mDeviceContext->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
648 ASSERT(SUCCEEDED(result));
649 memcpy(map.pData, vertexAttributes[0].mPointer, size);
650 mDeviceContext->Unmap(vertexBuffer, 0);
651
652 UINT offset = 0;
653 mDeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
654 vertexBuffer->Release();
655
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000656 // TODO: Build the input layout from the (translated) attribute information
657 D3D11_INPUT_ELEMENT_DESC inputElementDescriptions[1] =
658 {
659 {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}
660 };
661
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +0000662 ShaderExecutable *vertexExecutable = programBinary->getVertexExecutable();
663
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000664 ID3D11InputLayout *inputLayout = NULL;
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +0000665 result = mDevice->CreateInputLayout(inputElementDescriptions, 1, vertexExecutable->getFunction(), vertexExecutable->getLength(), &inputLayout);
daniel@transgaming.com18adad02012-11-28 21:04:03 +0000666 ASSERT(SUCCEEDED(result));
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000667
668 mDeviceContext->IASetInputLayout(inputLayout);
669 inputLayout->Release(); // TODO: Build a cache of input layouts
670
daniel@transgaming.com18adad02012-11-28 21:04:03 +0000671 return GL_NO_ERROR;
daniel@transgaming.comdef9f0f2012-11-28 20:53:20 +0000672}
673
daniel@transgaming.com31240482012-11-28 21:06:41 +0000674GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000675{
676 // TODO
677 UNIMPLEMENTED();
678
679 return GL_OUT_OF_MEMORY;
680}
681
682void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
683{
daniel@transgaming.comd4cf2512012-11-28 21:05:41 +0000684 mDeviceContext->Draw(count, 0);
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000685}
686
daniel@transgaming.com31240482012-11-28 21:06:41 +0000687void 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 +0000688{
689 // TODO
690 UNIMPLEMENTED();
691}
692
daniel@transgaming.com5fbf1772012-11-28 20:54:43 +0000693void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
694{
daniel@transgaming.come4991412012-12-20 20:55:34 +0000695 unsigned int programBinarySerial = programBinary->getSerial();
696 if (programBinarySerial != mAppliedProgramBinarySerial)
697 {
698 ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
699 ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000700
daniel@transgaming.come4991412012-12-20 20:55:34 +0000701 ID3D11VertexShader *vertexShader = NULL;
702 if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader();
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000703
daniel@transgaming.come4991412012-12-20 20:55:34 +0000704 ID3D11PixelShader *pixelShader = NULL;
705 if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000706
daniel@transgaming.come4991412012-12-20 20:55:34 +0000707 mDeviceContext->PSSetShader(pixelShader, NULL, 0);
708 mDeviceContext->VSSetShader(vertexShader, NULL, 0);
709 programBinary->dirtyAllUniforms();
710
711 mAppliedProgramBinarySerial = programBinarySerial;
712 }
daniel@transgaming.com5fbf1772012-11-28 20:54:43 +0000713}
714
daniel@transgaming.comab1c1462012-12-20 21:08:30 +0000715void Renderer11::applyUniforms(const gl::UniformArray *uniformArray)
716{
717 // TODO
718 if (uniformArray->size() != 0)
719 {
720 UNIMPLEMENTED();
721 }
722}
723
daniel@transgaming.com084a2572012-11-28 20:55:17 +0000724void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000725{
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000726 if (clearParams.mask & GL_COLOR_BUFFER_BIT)
727 {
728 gl::Renderbuffer *renderbufferObject = frameBuffer->getColorbuffer();
729 if (renderbufferObject)
730 {
731 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
732 if (!renderTarget)
733 {
734 ERR("render target pointer unexpectedly null.");
735 return;
736 }
737
738 ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
739 if (!framebufferRTV)
740 {
741 ERR("render target view pointer unexpectedly null.");
742 return;
743 }
744
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000745 if (mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
746 mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
747 mCurScissor.y + mCurScissor.height < renderTarget->getHeight()))
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000748 {
749 // TODO: clearing of subregion of render target
750 UNIMPLEMENTED();
751 }
752
753 bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha;
754 const bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) &&
755 !(clearParams.colorMaskRed && clearParams.colorMaskGreen &&
756 clearParams.colorMaskBlue && alphaUnmasked);
757
758 if (needMaskedColorClear)
759 {
760 // TODO: masked color clearing
761 UNIMPLEMENTED();
762 }
763 else
764 {
765 const float clearValues[4] = { clearParams.colorClearValue.red,
766 clearParams.colorClearValue.green,
767 clearParams.colorClearValue.blue,
768 clearParams.colorClearValue.alpha };
769 mDeviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
770 }
771
772 framebufferRTV->Release();
773 }
774 }
775 if (clearParams.mask & GL_DEPTH_BUFFER_BIT || clearParams.mask & GL_STENCIL_BUFFER_BIT)
776 {
777 gl::Renderbuffer *renderbufferObject = frameBuffer->getDepthOrStencilbuffer();
778 if (renderbufferObject)
779 {
780 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
781 if (!renderTarget)
782 {
783 ERR("render target pointer unexpectedly null.");
784 return;
785 }
786
787 ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
788 if (!framebufferDSV)
789 {
790 ERR("depth stencil view pointer unexpectedly null.");
791 return;
792 }
793
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000794 if (mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
795 mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
796 mCurScissor.y + mCurScissor.height < renderTarget->getHeight()))
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000797 {
798 // TODO: clearing of subregion of depth stencil view
799 UNIMPLEMENTED();
800 }
801
802 unsigned int stencilUnmasked = 0x0;
803 if ((clearParams.mask & GL_STENCIL_BUFFER_BIT) && frameBuffer->hasStencil())
804 {
805 unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat());
806 stencilUnmasked = (0x1 << stencilSize) - 1;
807 }
808
809 const bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) &&
810 (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
811
812 if (needMaskedStencilClear)
813 {
814 // TODO: masked clearing of depth stencil
815 UNIMPLEMENTED();
816 }
817 else
818 {
819 UINT clearFlags = 0;
820 if (clearParams.mask & GL_DEPTH_BUFFER_BIT)
821 {
822 clearFlags |= D3D11_CLEAR_DEPTH;
823 }
824 if (clearParams.mask & GL_STENCIL_BUFFER_BIT)
825 {
826 clearFlags |= D3D11_CLEAR_STENCIL;
827 }
828
829 float depthClear = clearParams.depthClearValue;
830 UINT8 stencilClear = clearParams.stencilClearValue & 0x000000FF;
831
832 mDeviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
833 }
834
835 framebufferDSV->Release();
836 }
837 }
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000838}
839
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000840void Renderer11::markAllStateDirty()
841{
daniel@transgaming.com9a067372012-12-20 20:55:24 +0000842 mAppliedRenderTargetSerial = 0;
843 mAppliedDepthbufferSerial = 0;
844 mAppliedStencilbufferSerial = 0;
daniel@transgaming.com7b6b83e2012-11-28 21:00:30 +0000845 mDepthStencilInitialized = false;
846 mRenderTargetDescInitialized = false;
847
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000848 mForceSetBlendState = true;
849 mForceSetRasterState = true;
850 mForceSetDepthStencilState = true;
851 mForceSetScissor = true;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000852 mForceSetViewport = true;
daniel@transgaming.come4991412012-12-20 20:55:34 +0000853
854 mAppliedProgramBinarySerial = 0;
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000855}
856
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000857void Renderer11::releaseDeviceResources()
858{
859 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000860 // UNIMPLEMENTED();
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000861 mStateCache.clear();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000862}
863
864void Renderer11::markDeviceLost()
865{
866 mDeviceLost = true;
867}
868
869bool Renderer11::isDeviceLost()
870{
871 return mDeviceLost;
872}
873
874// set notify to true to broadcast a message to all contexts of the device loss
875bool Renderer11::testDeviceLost(bool notify)
876{
877 bool isLost = false;
878
879 // TODO
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000880 //UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000881
882 if (isLost)
883 {
884 // ensure we note the device loss --
885 // we'll probably get this done again by markDeviceLost
886 // but best to remember it!
887 // Note that we don't want to clear the device loss status here
888 // -- this needs to be done by resetDevice
889 mDeviceLost = true;
890 if (notify)
891 {
892 mDisplay->notifyDeviceLost();
893 }
894 }
895
896 return isLost;
897}
898
899bool Renderer11::testDeviceResettable()
900{
901 HRESULT status = D3D_OK;
902
903 // TODO
904 UNIMPLEMENTED();
905
906 switch (status)
907 {
908 case D3DERR_DEVICENOTRESET:
909 case D3DERR_DEVICEHUNG:
910 return true;
911 default:
912 return false;
913 }
914}
915
916bool Renderer11::resetDevice()
917{
918 releaseDeviceResources();
919
920 // TODO
921 UNIMPLEMENTED();
922
923 // reset device defaults
924 initializeDevice();
925 mDeviceLost = false;
926
927 return true;
928}
929
930DWORD Renderer11::getAdapterVendor() const
931{
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000932 return mAdapterDescription.VendorId;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000933}
934
935const char *Renderer11::getAdapterDescription() const
936{
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000937 return mDescription;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000938}
939
940GUID Renderer11::getAdapterIdentifier() const
941{
942 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000943 // UNIMPLEMENTED();
944 GUID foo = {0};
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000945 return foo;
946}
947
948bool Renderer11::getDXT1TextureSupport()
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::getDXT3TextureSupport()
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::getDXT5TextureSupport()
963{
964 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000965 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000966 return false;
967}
968
969bool Renderer11::getDepthTextureSupport() const
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::getFloat32TextureSupport(bool *filtering, bool *renderable)
977{
978 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000979 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000980
981 *filtering = false;
982 *renderable = false;
983 return false;
984}
985
986bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
987{
988 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000989 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000990
991 *filtering = false;
992 *renderable = false;
993 return false;
994}
995
996bool Renderer11::getLuminanceTextureSupport()
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
1003bool Renderer11::getLuminanceAlphaTextureSupport()
1004{
1005 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001006 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001007 return false;
1008}
1009
1010bool Renderer11::getTextureFilterAnisotropySupport() const
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
1017float Renderer11::getTextureMaxAnisotropy() const
1018{
1019 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001020 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001021 return 1.0f;
1022}
1023
1024bool Renderer11::getEventQuerySupport()
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::getVertexTextureSupport() 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::getNonPower2TextureSupport() 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::getOcclusionQuerySupport() const
1046{
1047 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001048 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001049 return false;
1050}
1051
1052bool Renderer11::getInstancingSupport() const
1053{
1054 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001055 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001056 return false;
1057}
1058
1059bool Renderer11::getShareHandleSupport() const
1060{
1061 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001062 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001063
1064 // PIX doesn't seem to support using share handles, so disable them.
1065 return false && !gl::perfActive();
1066}
1067
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001068int Renderer11::getMajorShaderModel() const
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001069{
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001070 switch (mFeatureLevel)
1071 {
1072 case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5
1073 case D3D_FEATURE_LEVEL_10_1:
1074 case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4
1075 default: UNREACHABLE(); return 0;
1076 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001077}
1078
1079float Renderer11::getMaxPointSize() const
1080{
1081 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001082 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001083 return 1.0f;
1084}
1085
1086int Renderer11::getMaxTextureWidth() const
1087{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001088 switch (mFeatureLevel)
1089 {
1090 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
1091 case D3D_FEATURE_LEVEL_10_1:
1092 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
1093 default: UNREACHABLE(); return 0;
1094 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001095}
1096
1097int Renderer11::getMaxTextureHeight() const
1098{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001099 switch (mFeatureLevel)
1100 {
1101 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
1102 case D3D_FEATURE_LEVEL_10_1:
1103 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
1104 default: UNREACHABLE(); return 0;
1105 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001106}
1107
1108bool Renderer11::get32BitIndexSupport() const
1109{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001110 switch (mFeatureLevel)
1111 {
1112 case D3D_FEATURE_LEVEL_11_0:
1113 case D3D_FEATURE_LEVEL_10_1:
1114 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
1115 default: UNREACHABLE(); return false;
1116 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001117}
1118
1119int Renderer11::getMinSwapInterval() const
1120{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +00001121 return 0;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001122}
1123
1124int Renderer11::getMaxSwapInterval() const
1125{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +00001126 return 4;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001127}
1128
1129int Renderer11::getMaxSupportedSamples() const
1130{
1131 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001132 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001133 return 1;
1134}
1135
daniel@transgaming.com31b13e12012-11-28 19:34:30 +00001136bool Renderer11::copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +00001137{
1138 // TODO
1139 UNIMPLEMENTED();
1140 return false;
1141}
1142
daniel@transgaming.com31b13e12012-11-28 19:34:30 +00001143bool Renderer11::copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +00001144{
1145 // TODO
1146 UNIMPLEMENTED();
1147 return false;
1148}
1149
daniel@transgaming.com38380882012-11-28 19:36:39 +00001150bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
1151 GLint xoffset, GLint yoffset, TextureStorage2D *storage, GLint level)
1152{
1153 // TODO
1154 UNIMPLEMENTED();
1155 return false;
1156}
1157
1158bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
1159 GLint xoffset, GLint yoffset, TextureStorageCubeMap *storage, GLenum target, GLint level)
1160{
1161 // TODO
1162 UNIMPLEMENTED();
1163 return false;
1164}
1165
daniel@transgaming.comf2423652012-11-28 20:53:50 +00001166RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
1167{
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +00001168 SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
1169 RenderTarget11 *renderTarget = NULL;
1170 if (depth)
1171 {
1172 renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(), swapChain11->getWidth(), swapChain11->getHeight());
1173 }
1174 else
1175 {
1176 renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(), swapChain11->getWidth(), swapChain11->getHeight());
1177 }
1178 return renderTarget;
daniel@transgaming.comf2423652012-11-28 20:53:50 +00001179}
1180
1181RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth)
1182{
1183 // TODO
1184 UNIMPLEMENTED();
1185 return NULL;
1186}
1187
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001188ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, GLenum type, void *data)
daniel@transgaming.com55318902012-11-28 20:58:58 +00001189{
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001190 ShaderExecutable11 *executable = NULL;
1191
1192 switch (type)
1193 {
1194 case GL_VERTEX_SHADER:
1195 {
1196 ID3D11VertexShader *vshader = NULL;
1197 HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vshader);
1198 ASSERT(SUCCEEDED(result));
1199
1200 if (vshader)
1201 {
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001202 executable = new ShaderExecutable11(function, length, vshader);
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001203 }
1204 }
1205 break;
1206 case GL_FRAGMENT_SHADER:
1207 {
1208 ID3D11PixelShader *pshader = NULL;
1209 HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pshader);
1210 ASSERT(SUCCEEDED(result));
1211
1212 if (pshader)
1213 {
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001214 executable = new ShaderExecutable11(function, length, pshader);
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001215 }
1216 }
1217 break;
1218 default:
1219 UNREACHABLE();
1220 break;
1221 }
1222
1223 return executable;
daniel@transgaming.com55318902012-11-28 20:58:58 +00001224}
1225
daniel@transgaming.coma9c71422012-11-28 20:58:45 +00001226ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type)
1227{
daniel@transgaming.com071ee6a2012-11-28 21:03:21 +00001228 const char *profile = NULL;
1229
1230 switch (type)
1231 {
1232 case GL_VERTEX_SHADER:
1233 profile = "vs_4_0";
1234 break;
1235 case GL_FRAGMENT_SHADER:
1236 profile = "ps_4_0";
1237 break;
1238 default:
1239 UNREACHABLE();
1240 return NULL;
1241 }
1242
daniel@transgaming.com25e16af2012-11-28 21:05:57 +00001243 ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile, false);
daniel@transgaming.com071ee6a2012-11-28 21:03:21 +00001244 if (!binary)
1245 return NULL;
1246
1247 ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type, NULL);
1248 binary->Release();
1249
1250 return executable;
1251}
1252
daniel@transgaming.com3f255b42012-12-20 21:07:35 +00001253VertexBuffer *Renderer11::createVertexBuffer()
1254{
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +00001255 return new VertexBuffer11(this);
daniel@transgaming.com3f255b42012-12-20 21:07:35 +00001256}
1257
daniel@transgaming.com0b6d7742012-12-20 21:09:47 +00001258IndexBuffer *Renderer11::createIndexBuffer()
1259{
daniel@transgaming.com11c2af52012-12-20 21:10:01 +00001260 return new IndexBuffer11(this);
daniel@transgaming.com0b6d7742012-12-20 21:09:47 +00001261}
1262
daniel@transgaming.com6c872172012-11-28 19:39:33 +00001263bool Renderer11::blitRect(gl::Framebuffer *readTarget, gl::Rectangle *readRect, gl::Framebuffer *drawTarget, gl::Rectangle *drawRect,
1264 bool blitRenderTarget, bool blitDepthStencil)
1265{
1266 // TODO
1267 UNIMPLEMENTED();
1268 return false;
1269}
1270
1271void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
1272 GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels)
1273{
1274 // TODO
1275 UNIMPLEMENTED();
1276 return;
1277}
1278
daniel@transgaming.com244e1832012-12-20 20:52:35 +00001279Image *Renderer11::createImage()
1280{
daniel@transgaming.coma8aac672012-12-20 21:08:00 +00001281 return new Image11();
daniel@transgaming.com244e1832012-12-20 20:52:35 +00001282}
1283
daniel@transgaming.comf721fdb2012-12-20 20:53:11 +00001284void Renderer11::generateMipmap(Image *dest, Image *src)
1285{
1286 // TODO
1287 UNIMPLEMENTED();
1288 return;
1289}
1290
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001291}