blob: 71b9ca0e3ca72084d7d351303946f694315be9f8 [file] [log] [blame]
daniel@transgaming.com32fdf822012-11-28 20:53:30 +00001//
daniel@transgaming.comed36abd2013-01-11 21:15:58 +00002// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com32fdf822012-11-28 20:53:30 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.
8
9#include "libGLESv2/renderer/SwapChain11.h"
10
11#include "common/debug.h"
12#include "libGLESv2/utilities.h"
13#include "libGLESv2/renderer/renderer11_utils.h"
14#include "libGLESv2/renderer/Renderer11.h"
15#include "libGLESv2/Context.h"
16#include "libGLESv2/main.h"
17
daniel@transgaming.com8dc8e272013-01-11 04:10:45 +000018#include "libGLESv2/renderer/shaders/compiled/passthrough11vs.h"
shannon.woods@transgaming.com2570c342013-01-25 21:50:22 +000019#include "libGLESv2/renderer/shaders/compiled/passthroughrgba11ps.h"
daniel@transgaming.come0970472012-11-28 21:05:07 +000020
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000021namespace rx
22{
23
24SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
25 GLenum backBufferFormat, GLenum depthBufferFormat)
26 : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
27{
28 mSwapChain = NULL;
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000029 mBackBufferTexture = NULL;
30 mBackBufferRTView = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000031 mOffscreenTexture = NULL;
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000032 mOffscreenRTView = NULL;
daniel@transgaming.come0970472012-11-28 21:05:07 +000033 mOffscreenSRView = NULL;
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000034 mDepthStencilTexture = NULL;
35 mDepthStencilDSView = NULL;
daniel@transgaming.comf06e5392013-01-11 21:15:50 +000036 mQuadVB = NULL;
37 mPassThroughSampler = NULL;
38 mPassThroughIL = NULL;
39 mPassThroughVS = NULL;
40 mPassThroughPS = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000041 mWidth = -1;
42 mHeight = -1;
shannon.woods@transgaming.comad74a4b2013-02-28 23:04:09 +000043 mSwapInterval = 0;
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +000044 mAppCreatedShareHandle = mShareHandle != NULL;
shannon.woods@transgaming.com211fa2e2013-02-28 23:05:23 +000045 mPassThroughResourcesInit = false;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000046}
47
48SwapChain11::~SwapChain11()
49{
50 release();
51}
52
53void SwapChain11::release()
54{
55 if (mSwapChain)
56 {
57 mSwapChain->Release();
58 mSwapChain = NULL;
59 }
60
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000061 if (mBackBufferTexture)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000062 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000063 mBackBufferTexture->Release();
64 mBackBufferTexture = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000065 }
66
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000067 if (mBackBufferRTView)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000068 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000069 mBackBufferRTView->Release();
70 mBackBufferRTView = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000071 }
72
73 if (mOffscreenTexture)
74 {
75 mOffscreenTexture->Release();
76 mOffscreenTexture = NULL;
77 }
78
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000079 if (mOffscreenRTView)
80 {
81 mOffscreenRTView->Release();
82 mOffscreenRTView = NULL;
83 }
84
daniel@transgaming.come0970472012-11-28 21:05:07 +000085 if (mOffscreenSRView)
86 {
87 mOffscreenSRView->Release();
88 mOffscreenSRView = NULL;
89 }
90
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000091 if (mDepthStencilTexture)
92 {
93 mDepthStencilTexture->Release();
94 mDepthStencilTexture = NULL;
95 }
96
97 if (mDepthStencilDSView)
98 {
99 mDepthStencilDSView->Release();
100 mDepthStencilDSView = NULL;
101 }
102
daniel@transgaming.come0970472012-11-28 21:05:07 +0000103 if (mQuadVB)
104 {
105 mQuadVB->Release();
106 mQuadVB = NULL;
107 }
108
109 if (mPassThroughSampler)
110 {
111 mPassThroughSampler->Release();
112 mPassThroughSampler = NULL;
113 }
114
115 if (mPassThroughIL)
116 {
117 mPassThroughIL->Release();
118 mPassThroughIL = NULL;
119 }
120
121 if (mPassThroughVS)
122 {
123 mPassThroughVS->Release();
124 mPassThroughVS = NULL;
125 }
126
127 if (mPassThroughPS)
128 {
129 mPassThroughPS->Release();
130 mPassThroughPS = NULL;
131 }
132
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000133 if (!mAppCreatedShareHandle)
134 {
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000135 mShareHandle = NULL;
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000136 }
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000137}
138
shannon.woods@transgaming.comae813832013-02-28 23:05:28 +0000139EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHeight)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000140{
141 ID3D11Device *device = mRenderer->getDevice();
142
143 if (device == NULL)
144 {
145 return EGL_BAD_ACCESS;
146 }
147
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000148 if (mOffscreenTexture)
149 {
150 mOffscreenTexture->Release();
151 mOffscreenTexture = NULL;
152 }
153
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000154 if (mOffscreenRTView) // TODO: Preserve the render target content
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000155 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000156 mOffscreenRTView->Release();
157 mOffscreenRTView = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000158 }
159
daniel@transgaming.come0970472012-11-28 21:05:07 +0000160 if (mOffscreenSRView)
161 {
162 mOffscreenSRView->Release();
163 mOffscreenSRView = NULL;
164 }
165
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000166 if (mDepthStencilTexture)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000167 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000168 mDepthStencilTexture->Release();
169 mDepthStencilTexture = NULL;
170 }
171
172 if (mDepthStencilDSView)
173 {
174 mDepthStencilDSView->Release();
175 mDepthStencilDSView = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000176 }
177
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000178 // If the app passed in a share handle, open the resource
179 // See EGL_ANGLE_d3d_share_handle_client_buffer
180 if (mAppCreatedShareHandle)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000181 {
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000182 ID3D11Resource *tempResource11;
183 HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000184
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000185 if (FAILED(result))
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000186 {
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000187 ERR("Failed to open the swap chain pbuffer share handle: %08lX", result);
188 release();
189 return EGL_BAD_PARAMETER;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000190 }
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000191
192 result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture);
193 tempResource11->Release();
194
195 if (FAILED(result))
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000196 {
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000197 ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result);
198 release();
199 return EGL_BAD_PARAMETER;
200 }
201
202 // Validate offscreen texture parameters
203 D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
204 mOffscreenTexture->GetDesc(&offscreenTextureDesc);
205
206 if (offscreenTextureDesc.Width != (UINT)backbufferWidth
207 || offscreenTextureDesc.Height != (UINT)backbufferHeight
208 || offscreenTextureDesc.Format != gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat)
209 || offscreenTextureDesc.MipLevels != 1
210 || offscreenTextureDesc.ArraySize != 1)
211 {
212 ERR("Invalid texture parameters in the shared offscreen texture pbuffer");
213 release();
214 return EGL_BAD_PARAMETER;
215 }
216 }
217 else
218 {
219 const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport();
220
221 D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
222 offscreenTextureDesc.Width = backbufferWidth;
223 offscreenTextureDesc.Height = backbufferHeight;
224 offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
225 offscreenTextureDesc.MipLevels = 1;
226 offscreenTextureDesc.ArraySize = 1;
227 offscreenTextureDesc.SampleDesc.Count = 1;
228 offscreenTextureDesc.SampleDesc.Quality = 0;
229 offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
230 offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
231 offscreenTextureDesc.CPUAccessFlags = 0;
232 offscreenTextureDesc.MiscFlags = useSharedResource ? D3D11_RESOURCE_MISC_SHARED : 0;
233
234 HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture);
235
236 if (FAILED(result))
237 {
238 ERR("Could not create offscreen texture: %08lX", result);
239 release();
240
shannon.woods@transgaming.comf5f59492013-02-28 23:04:40 +0000241 if (d3d11::isDeviceLostError(result))
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000242 {
243 return EGL_CONTEXT_LOST;
244 }
245 else
246 {
247 return EGL_BAD_ALLOC;
248 }
249 }
250
251 d3d11::SetDebugName(mOffscreenTexture, "Offscreen texture");
252
253 // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client
254 if (useSharedResource)
255 {
256 IDXGIResource *offscreenTextureResource = NULL;
257 result = mOffscreenTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&offscreenTextureResource);
258
259 // Fall back to no share handle on failure
260 if (FAILED(result))
261 {
262 ERR("Could not query offscreen texture resource: %08lX", result);
263 }
264 else
265 {
266 result = offscreenTextureResource->GetSharedHandle(&mShareHandle);
267
268 if (FAILED(result))
269 {
270 mShareHandle = NULL;
271 ERR("Could not get offscreen texture shared handle: %08lX", result);
272 }
273 }
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000274 }
275 }
276
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000277 HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, NULL, &mOffscreenRTView);
278
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000279 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000280 d3d11::SetDebugName(mOffscreenRTView, "Offscreen render target");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000281
daniel@transgaming.come0970472012-11-28 21:05:07 +0000282 result = device->CreateShaderResourceView(mOffscreenTexture, NULL, &mOffscreenSRView);
283 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000284 d3d11::SetDebugName(mOffscreenSRView, "Offscreen shader resource");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000285
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000286 if (mDepthBufferFormat != GL_NONE)
287 {
288 D3D11_TEXTURE2D_DESC depthStencilDesc = {0};
289 depthStencilDesc.Width = backbufferWidth;
290 depthStencilDesc.Height = backbufferHeight;
291 depthStencilDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mDepthBufferFormat);
292 depthStencilDesc.MipLevels = 1;
293 depthStencilDesc.ArraySize = 1;
294 depthStencilDesc.SampleDesc.Count = 1;
295 depthStencilDesc.SampleDesc.Quality = 0;
296 depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
297 depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
298 depthStencilDesc.CPUAccessFlags = 0;
299 depthStencilDesc.MiscFlags = 0;
300
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000301 result = device->CreateTexture2D(&depthStencilDesc, NULL, &mDepthStencilTexture);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000302 if (FAILED(result))
303 {
304 ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
305 release();
306
shannon.woods@transgaming.comf5f59492013-02-28 23:04:40 +0000307 if (d3d11::isDeviceLostError(result))
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000308 {
309 return EGL_CONTEXT_LOST;
310 }
311 else
312 {
313 return EGL_BAD_ALLOC;
314 }
315 }
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000316 d3d11::SetDebugName(mDepthStencilTexture, "Depth stencil texture");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000317
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000318 result = device->CreateDepthStencilView(mDepthStencilTexture, NULL, &mDepthStencilDSView);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000319 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000320 d3d11::SetDebugName(mDepthStencilDSView, "Depth stencil view");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000321 }
322
shannon.woods@transgaming.comae813832013-02-28 23:05:28 +0000323 mWidth = backbufferWidth;
324 mHeight = backbufferHeight;
325
326 return EGL_SUCCESS;
327}
328
329EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
330{
331 ID3D11Device *device = mRenderer->getDevice();
332
333 if (device == NULL)
334 {
335 return EGL_BAD_ACCESS;
336 }
337
338 // Release specific resources to free up memory for the new render target, while the
339 // old render target still exists for the purpose of preserving its contents.
340 if (mSwapChain)
341 {
342 mSwapChain->Release();
343 mSwapChain = NULL;
344 }
345
346 if (mBackBufferTexture)
347 {
348 mBackBufferTexture->Release();
349 mBackBufferTexture = NULL;
350 }
351
352 if (mBackBufferRTView)
353 {
354 mBackBufferRTView->Release();
355 mBackBufferRTView = NULL;
356 }
357
358 mSwapInterval = static_cast<unsigned int>(swapInterval);
359 if (mSwapInterval > 4)
360 {
361 // IDXGISwapChain::Present documentation states that valid sync intervals are in the [0,4] range
362 return EGL_BAD_PARAMETER;
363 }
364
365 if (mWindow)
366 {
367 // We cannot create a swap chain for an HWND that is owned by a different process
368 DWORD currentProcessId = GetCurrentProcessId();
369 DWORD wndProcessId;
370 GetWindowThreadProcessId(mWindow, &wndProcessId);
371
372 if (currentProcessId != wndProcessId)
373 {
374 ERR("Could not create swap chain, window owned by different process");
375 release();
376 return EGL_BAD_NATIVE_WINDOW;
377 }
378
379 IDXGIFactory *factory = mRenderer->getDxgiFactory();
380
381 DXGI_SWAP_CHAIN_DESC swapChainDesc = {0};
382 swapChainDesc.BufferCount = 2;
383 swapChainDesc.BufferDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
384 swapChainDesc.BufferDesc.Width = backbufferWidth;
385 swapChainDesc.BufferDesc.Height = backbufferHeight;
386 swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
387 swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
388 swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
389 swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
390 swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
391 swapChainDesc.Flags = 0;
392 swapChainDesc.OutputWindow = mWindow;
393 swapChainDesc.SampleDesc.Count = 1;
394 swapChainDesc.SampleDesc.Quality = 0;
395 swapChainDesc.Windowed = TRUE;
396
397 HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
398
399 if (FAILED(result))
400 {
401 ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
402 release();
403
404 if (d3d11::isDeviceLostError(result))
405 {
406 return EGL_CONTEXT_LOST;
407 }
408 else
409 {
410 return EGL_BAD_ALLOC;
411 }
412 }
413
414 result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture);
415 ASSERT(SUCCEEDED(result));
416 d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture");
417
418 result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView);
419 ASSERT(SUCCEEDED(result));
420 d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
421 }
422
shannon.woods@transgaming.com211fa2e2013-02-28 23:05:23 +0000423 // If we are resizing the swap chain, we don't wish to recreate all the static resources
424 if (!mPassThroughResourcesInit)
425 {
426 mPassThroughResourcesInit = true;
427 initPassThroughResources();
428 }
429
shannon.woods@transgaming.comae813832013-02-28 23:05:28 +0000430 return resetOffscreenTexture(backbufferWidth, backbufferHeight);
shannon.woods@transgaming.com211fa2e2013-02-28 23:05:23 +0000431}
432
433void SwapChain11::initPassThroughResources()
434{
435 ID3D11Device *device = mRenderer->getDevice();
436
437 ASSERT(device != NULL);
438
439 // Make sure our resources are all not allocated, when we create
440 ASSERT(mQuadVB == NULL && mPassThroughSampler == NULL);
441 ASSERT(mPassThroughIL == NULL && mPassThroughVS == NULL && mPassThroughPS == NULL);
442
daniel@transgaming.come0970472012-11-28 21:05:07 +0000443 D3D11_BUFFER_DESC vbDesc;
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +0000444 vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4;
daniel@transgaming.come0970472012-11-28 21:05:07 +0000445 vbDesc.Usage = D3D11_USAGE_DYNAMIC;
446 vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
447 vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
448 vbDesc.MiscFlags = 0;
449 vbDesc.StructureByteStride = 0;
450
shannon.woods@transgaming.com211fa2e2013-02-28 23:05:23 +0000451 HRESULT result = device->CreateBuffer(&vbDesc, NULL, &mQuadVB);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000452 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000453 d3d11::SetDebugName(mQuadVB, "Swap chain quad vertex buffer");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000454
455 D3D11_SAMPLER_DESC samplerDesc;
456 samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
457 samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
458 samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
459 samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
460 samplerDesc.MipLODBias = 0.0f;
461 samplerDesc.MaxAnisotropy = 0;
462 samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
463 samplerDesc.BorderColor[0] = 0.0f;
464 samplerDesc.BorderColor[1] = 0.0f;
465 samplerDesc.BorderColor[2] = 0.0f;
466 samplerDesc.BorderColor[3] = 0.0f;
467 samplerDesc.MinLOD = 0;
468 samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
469
470 result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler);
471 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000472 d3d11::SetDebugName(mPassThroughSampler, "Swap chain pass through sampler");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000473
474 D3D11_INPUT_ELEMENT_DESC quadLayout[] =
475 {
476 { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
477 { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
478 };
479
480 result = device->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mPassThroughIL);
481 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000482 d3d11::SetDebugName(mPassThroughIL, "Swap chain pass through layout");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000483
484 result = device->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mPassThroughVS);
485 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000486 d3d11::SetDebugName(mPassThroughVS, "Swap chain pass through vertex shader");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000487
shannon.woods@transgaming.com2570c342013-01-25 21:50:22 +0000488 result = device->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mPassThroughPS);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000489 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000490 d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000491}
492
493// parameters should be validated/clamped by caller
494EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
495{
496 if (!mSwapChain)
497 {
498 return EGL_SUCCESS;
499 }
500
501 ID3D11Device *device = mRenderer->getDevice();
daniel@transgaming.come0970472012-11-28 21:05:07 +0000502 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000503
daniel@transgaming.come0970472012-11-28 21:05:07 +0000504 // Set vertices
505 D3D11_MAPPED_SUBRESOURCE mappedResource;
506 HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
507 if (FAILED(result))
508 {
509 return EGL_BAD_ACCESS;
510 }
511
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +0000512 d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000513
514 // Create a quad in homogeneous coordinates
shannon.woods@transgaming.com2ac02d52013-01-25 21:56:54 +0000515 float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
516 float y1 = ((mHeight - y - height) / float(mHeight)) * 2.0f - 1.0f;
517 float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f;
518 float y2 = ((mHeight - y) / float(mHeight)) * 2.0f - 1.0f;
daniel@transgaming.come0970472012-11-28 21:05:07 +0000519
520 float u1 = x / float(mWidth);
521 float v1 = y / float(mHeight);
522 float u2 = (x + width) / float(mWidth);
523 float v2 = (y + height) / float(mHeight);
524
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +0000525 d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1);
526 d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
527 d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
528 d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000529
530 deviceContext->Unmap(mQuadVB, 0);
531
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +0000532 static UINT stride = sizeof(d3d11::PositionTexCoordVertex);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000533 static UINT startIdx = 0;
534 deviceContext->IASetVertexBuffers(0, 1, &mQuadVB, &stride, &startIdx);
535
536 // Apply state
537 deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
538
539 static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
540 deviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFF);
541
542 deviceContext->RSSetState(NULL);
543
544 // Apply shaders
545 deviceContext->IASetInputLayout(mPassThroughIL);
546 deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
547 deviceContext->VSSetShader(mPassThroughVS, NULL, 0);
548 deviceContext->PSSetShader(mPassThroughPS, NULL, 0);
shannon.woods@transgaming.com3e773bb2013-01-25 21:55:47 +0000549 deviceContext->GSSetShader(NULL, NULL, 0);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000550
551 // Apply render targets
552 deviceContext->OMSetRenderTargets(1, &mBackBufferRTView, NULL);
553
daniel@transgaming.com9799a2f2013-01-11 04:09:27 +0000554 // Set the viewport
555 D3D11_VIEWPORT viewport;
556 viewport.TopLeftX = 0;
557 viewport.TopLeftY = 0;
558 viewport.Width = mWidth;
559 viewport.Height = mHeight;
560 viewport.MinDepth = 0.0f;
561 viewport.MaxDepth = 1.0f;
562 deviceContext->RSSetViewports(1, &viewport);
563
daniel@transgaming.come0970472012-11-28 21:05:07 +0000564 // Apply textures
565 deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView);
566 deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler);
567
568 // Draw
569 deviceContext->Draw(4, 0);
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +0000570 result = mSwapChain->Present(mSwapInterval, 0);
571
572 if (result == DXGI_ERROR_DEVICE_REMOVED)
573 {
574 HRESULT removedReason = device->GetDeviceRemovedReason();
575 ERR("Present failed: the D3D11 device was removed: 0x%08X", removedReason);
576 return EGL_CONTEXT_LOST;
577 }
578 else if (result == DXGI_ERROR_DEVICE_RESET)
579 {
580 ERR("Present failed: the D3D11 device was reset from a bad command.");
581 return EGL_CONTEXT_LOST;
582 }
583 else if (FAILED(result))
584 {
585 ERR("Present failed with error code 0x%08X", result);
586 }
daniel@transgaming.come0970472012-11-28 21:05:07 +0000587
588 // Unbind
589 static ID3D11ShaderResourceView *const nullSRV = NULL;
590 deviceContext->PSSetShaderResources(0, 1, &nullSRV);
591
592 static ID3D11RenderTargetView *const nullRTV = NULL;
593 deviceContext->OMSetRenderTargets(1, &nullRTV, NULL);
594
daniel@transgaming.come0970472012-11-28 21:05:07 +0000595 mRenderer->markAllStateDirty();
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000596
597 return EGL_SUCCESS;
598}
599
shannon.woods@transgaming.com5c25ed22013-01-25 21:49:51 +0000600// Increments refcount on texture.
601// caller must Release() the returned texture
602ID3D11Texture2D *SwapChain11::getOffscreenTexture()
603{
604 if (mOffscreenTexture)
605 {
606 mOffscreenTexture->AddRef();
607 }
608
609 return mOffscreenTexture;
610}
611
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000612// Increments refcount on view.
613// caller must Release() the returned view
614ID3D11RenderTargetView *SwapChain11::getRenderTarget()
615{
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000616 if (mOffscreenRTView)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000617 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000618 mOffscreenRTView->AddRef();
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000619 }
620
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000621 return mOffscreenRTView;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000622}
623
624// Increments refcount on view.
625// caller must Release() the returned view
shannon.woods@transgaming.com5c25ed22013-01-25 21:49:51 +0000626ID3D11ShaderResourceView *SwapChain11::getRenderTargetShaderResource()
627{
628 if (mOffscreenSRView)
629 {
630 mOffscreenSRView->AddRef();
631 }
632
633 return mOffscreenSRView;
634}
635
636// Increments refcount on view.
637// caller must Release() the returned view
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000638ID3D11DepthStencilView *SwapChain11::getDepthStencil()
639{
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000640 if (mDepthStencilDSView)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000641 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000642 mDepthStencilDSView->AddRef();
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000643 }
644
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000645 return mDepthStencilDSView;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000646}
647
daniel@transgaming.comd733bb82012-11-28 20:53:40 +0000648SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain)
649{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +0000650 ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain11*, swapChain));
daniel@transgaming.comd733bb82012-11-28 20:53:40 +0000651 return static_cast<rx::SwapChain11*>(swapChain);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000652}
daniel@transgaming.comd733bb82012-11-28 20:53:40 +0000653
654}