blob: fa356fbd9e2840c096989ae89b2f9cf8bac7ba79 [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;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000045}
46
47SwapChain11::~SwapChain11()
48{
49 release();
50}
51
52void SwapChain11::release()
53{
54 if (mSwapChain)
55 {
56 mSwapChain->Release();
57 mSwapChain = NULL;
58 }
59
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000060 if (mBackBufferTexture)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000061 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000062 mBackBufferTexture->Release();
63 mBackBufferTexture = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000064 }
65
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000066 if (mBackBufferRTView)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000067 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000068 mBackBufferRTView->Release();
69 mBackBufferRTView = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000070 }
71
72 if (mOffscreenTexture)
73 {
74 mOffscreenTexture->Release();
75 mOffscreenTexture = NULL;
76 }
77
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000078 if (mOffscreenRTView)
79 {
80 mOffscreenRTView->Release();
81 mOffscreenRTView = NULL;
82 }
83
daniel@transgaming.come0970472012-11-28 21:05:07 +000084 if (mOffscreenSRView)
85 {
86 mOffscreenSRView->Release();
87 mOffscreenSRView = NULL;
88 }
89
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000090 if (mDepthStencilTexture)
91 {
92 mDepthStencilTexture->Release();
93 mDepthStencilTexture = NULL;
94 }
95
96 if (mDepthStencilDSView)
97 {
98 mDepthStencilDSView->Release();
99 mDepthStencilDSView = NULL;
100 }
101
daniel@transgaming.come0970472012-11-28 21:05:07 +0000102 if (mQuadVB)
103 {
104 mQuadVB->Release();
105 mQuadVB = NULL;
106 }
107
108 if (mPassThroughSampler)
109 {
110 mPassThroughSampler->Release();
111 mPassThroughSampler = NULL;
112 }
113
114 if (mPassThroughIL)
115 {
116 mPassThroughIL->Release();
117 mPassThroughIL = NULL;
118 }
119
120 if (mPassThroughVS)
121 {
122 mPassThroughVS->Release();
123 mPassThroughVS = NULL;
124 }
125
126 if (mPassThroughPS)
127 {
128 mPassThroughPS->Release();
129 mPassThroughPS = NULL;
130 }
131
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000132 if (!mAppCreatedShareHandle)
133 {
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000134 mShareHandle = NULL;
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000135 }
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000136}
137
138EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
139{
140 ID3D11Device *device = mRenderer->getDevice();
141
142 if (device == NULL)
143 {
144 return EGL_BAD_ACCESS;
145 }
146
147 // Release specific resources to free up memory for the new render target, while the
148 // old render target still exists for the purpose of preserving its contents.
149 if (mSwapChain)
150 {
151 mSwapChain->Release();
152 mSwapChain = NULL;
153 }
154
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000155 if (mBackBufferTexture)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000156 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000157 mBackBufferTexture->Release();
158 mBackBufferTexture = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000159 }
160
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000161 if (mBackBufferRTView)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000162 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000163 mBackBufferRTView->Release();
164 mBackBufferRTView = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000165 }
166
167 if (mOffscreenTexture)
168 {
169 mOffscreenTexture->Release();
170 mOffscreenTexture = NULL;
171 }
172
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000173 if (mOffscreenRTView) // TODO: Preserve the render target content
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000174 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000175 mOffscreenRTView->Release();
176 mOffscreenRTView = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000177 }
178
daniel@transgaming.come0970472012-11-28 21:05:07 +0000179 if (mOffscreenSRView)
180 {
181 mOffscreenSRView->Release();
182 mOffscreenSRView = NULL;
183 }
184
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000185 if (mDepthStencilTexture)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000186 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000187 mDepthStencilTexture->Release();
188 mDepthStencilTexture = NULL;
189 }
190
191 if (mDepthStencilDSView)
192 {
193 mDepthStencilDSView->Release();
194 mDepthStencilDSView = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000195 }
196
shannon.woods@transgaming.comad74a4b2013-02-28 23:04:09 +0000197 mSwapInterval = static_cast<unsigned int>(swapInterval);
198 if (mSwapInterval > 4)
199 {
200 // IDXGISwapChain::Present documentation states that valid sync intervals are in the [0,4] range
201 return EGL_BAD_PARAMETER;
202 }
203
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000204 // If the app passed in a share handle, open the resource
205 // See EGL_ANGLE_d3d_share_handle_client_buffer
206 if (mAppCreatedShareHandle)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000207 {
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000208 ID3D11Resource *tempResource11;
209 HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000210
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000211 if (FAILED(result))
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000212 {
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000213 ERR("Failed to open the swap chain pbuffer share handle: %08lX", result);
214 release();
215 return EGL_BAD_PARAMETER;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000216 }
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000217
218 result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture);
219 tempResource11->Release();
220
221 if (FAILED(result))
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000222 {
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000223 ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result);
224 release();
225 return EGL_BAD_PARAMETER;
226 }
227
228 // Validate offscreen texture parameters
229 D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
230 mOffscreenTexture->GetDesc(&offscreenTextureDesc);
231
232 if (offscreenTextureDesc.Width != (UINT)backbufferWidth
233 || offscreenTextureDesc.Height != (UINT)backbufferHeight
234 || offscreenTextureDesc.Format != gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat)
235 || offscreenTextureDesc.MipLevels != 1
236 || offscreenTextureDesc.ArraySize != 1)
237 {
238 ERR("Invalid texture parameters in the shared offscreen texture pbuffer");
239 release();
240 return EGL_BAD_PARAMETER;
241 }
242 }
243 else
244 {
245 const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport();
246
247 D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
248 offscreenTextureDesc.Width = backbufferWidth;
249 offscreenTextureDesc.Height = backbufferHeight;
250 offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
251 offscreenTextureDesc.MipLevels = 1;
252 offscreenTextureDesc.ArraySize = 1;
253 offscreenTextureDesc.SampleDesc.Count = 1;
254 offscreenTextureDesc.SampleDesc.Quality = 0;
255 offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
256 offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
257 offscreenTextureDesc.CPUAccessFlags = 0;
258 offscreenTextureDesc.MiscFlags = useSharedResource ? D3D11_RESOURCE_MISC_SHARED : 0;
259
260 HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture);
261
262 if (FAILED(result))
263 {
264 ERR("Could not create offscreen texture: %08lX", result);
265 release();
266
267 if (isDeviceLostError(result))
268 {
269 return EGL_CONTEXT_LOST;
270 }
271 else
272 {
273 return EGL_BAD_ALLOC;
274 }
275 }
276
277 d3d11::SetDebugName(mOffscreenTexture, "Offscreen texture");
278
279 // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client
280 if (useSharedResource)
281 {
282 IDXGIResource *offscreenTextureResource = NULL;
283 result = mOffscreenTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&offscreenTextureResource);
284
285 // Fall back to no share handle on failure
286 if (FAILED(result))
287 {
288 ERR("Could not query offscreen texture resource: %08lX", result);
289 }
290 else
291 {
292 result = offscreenTextureResource->GetSharedHandle(&mShareHandle);
293
294 if (FAILED(result))
295 {
296 mShareHandle = NULL;
297 ERR("Could not get offscreen texture shared handle: %08lX", result);
298 }
299 }
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000300 }
301 }
302
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000303 HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, NULL, &mOffscreenRTView);
304
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000305 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000306 d3d11::SetDebugName(mOffscreenRTView, "Offscreen render target");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000307
daniel@transgaming.come0970472012-11-28 21:05:07 +0000308 result = device->CreateShaderResourceView(mOffscreenTexture, NULL, &mOffscreenSRView);
309 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000310 d3d11::SetDebugName(mOffscreenSRView, "Offscreen shader resource");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000311
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000312 if (mWindow)
313 {
shannon.woods@transgaming.com7d4b4822013-01-25 21:52:27 +0000314 // We cannot create a swap chain for an HWND that is owned by a different process
315 DWORD currentProcessId = GetCurrentProcessId();
316 DWORD wndProcessId;
317 GetWindowThreadProcessId(mWindow, &wndProcessId);
318
319 if (currentProcessId != wndProcessId)
320 {
321 ERR("Could not create swap chain, window owned by different process");
322 release();
323 return EGL_BAD_NATIVE_WINDOW;
324 }
325
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000326 IDXGIFactory *factory = mRenderer->getDxgiFactory();
327
328 DXGI_SWAP_CHAIN_DESC swapChainDesc = {0};
329 swapChainDesc.BufferCount = 2;
330 swapChainDesc.BufferDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
daniel@transgaming.com567b9cf2012-11-28 21:04:46 +0000331 swapChainDesc.BufferDesc.Width = backbufferWidth;
332 swapChainDesc.BufferDesc.Height = backbufferHeight;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000333 swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
334 swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
335 swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
336 swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
337 swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
338 swapChainDesc.Flags = 0;
339 swapChainDesc.OutputWindow = mWindow;
340 swapChainDesc.SampleDesc.Count = 1;
341 swapChainDesc.SampleDesc.Quality = 0;
342 swapChainDesc.Windowed = TRUE;
343
344 result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
345
346 if (FAILED(result))
347 {
348 ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
349 release();
350
351 if (isDeviceLostError(result))
352 {
353 return EGL_CONTEXT_LOST;
354 }
355 else
356 {
357 return EGL_BAD_ALLOC;
358 }
359 }
360
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000361 result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000362 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000363 d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000364
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000365 result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000366 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000367 d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000368 }
369
370 if (mDepthBufferFormat != GL_NONE)
371 {
372 D3D11_TEXTURE2D_DESC depthStencilDesc = {0};
373 depthStencilDesc.Width = backbufferWidth;
374 depthStencilDesc.Height = backbufferHeight;
375 depthStencilDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mDepthBufferFormat);
376 depthStencilDesc.MipLevels = 1;
377 depthStencilDesc.ArraySize = 1;
378 depthStencilDesc.SampleDesc.Count = 1;
379 depthStencilDesc.SampleDesc.Quality = 0;
380 depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
381 depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
382 depthStencilDesc.CPUAccessFlags = 0;
383 depthStencilDesc.MiscFlags = 0;
384
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000385 result = device->CreateTexture2D(&depthStencilDesc, NULL, &mDepthStencilTexture);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000386 if (FAILED(result))
387 {
388 ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
389 release();
390
391 if (isDeviceLostError(result))
392 {
393 return EGL_CONTEXT_LOST;
394 }
395 else
396 {
397 return EGL_BAD_ALLOC;
398 }
399 }
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000400 d3d11::SetDebugName(mDepthStencilTexture, "Depth stencil texture");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000401
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000402 result = device->CreateDepthStencilView(mDepthStencilTexture, NULL, &mDepthStencilDSView);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000403 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000404 d3d11::SetDebugName(mDepthStencilDSView, "Depth stencil view");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000405 }
406
daniel@transgaming.come0970472012-11-28 21:05:07 +0000407 D3D11_BUFFER_DESC vbDesc;
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +0000408 vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4;
daniel@transgaming.come0970472012-11-28 21:05:07 +0000409 vbDesc.Usage = D3D11_USAGE_DYNAMIC;
410 vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
411 vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
412 vbDesc.MiscFlags = 0;
413 vbDesc.StructureByteStride = 0;
414
415 result = device->CreateBuffer(&vbDesc, NULL, &mQuadVB);
416 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000417 d3d11::SetDebugName(mQuadVB, "Swap chain quad vertex buffer");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000418
419 D3D11_SAMPLER_DESC samplerDesc;
420 samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
421 samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
422 samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
423 samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
424 samplerDesc.MipLODBias = 0.0f;
425 samplerDesc.MaxAnisotropy = 0;
426 samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
427 samplerDesc.BorderColor[0] = 0.0f;
428 samplerDesc.BorderColor[1] = 0.0f;
429 samplerDesc.BorderColor[2] = 0.0f;
430 samplerDesc.BorderColor[3] = 0.0f;
431 samplerDesc.MinLOD = 0;
432 samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
433
434 result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler);
435 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000436 d3d11::SetDebugName(mPassThroughSampler, "Swap chain pass through sampler");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000437
438 D3D11_INPUT_ELEMENT_DESC quadLayout[] =
439 {
440 { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
441 { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
442 };
443
444 result = device->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mPassThroughIL);
445 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000446 d3d11::SetDebugName(mPassThroughIL, "Swap chain pass through layout");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000447
448 result = device->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mPassThroughVS);
449 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000450 d3d11::SetDebugName(mPassThroughVS, "Swap chain pass through vertex shader");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000451
shannon.woods@transgaming.com2570c342013-01-25 21:50:22 +0000452 result = device->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mPassThroughPS);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000453 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000454 d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000455
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000456 mWidth = backbufferWidth;
457 mHeight = backbufferHeight;
458
459 return EGL_SUCCESS;
460}
461
462// parameters should be validated/clamped by caller
463EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
464{
465 if (!mSwapChain)
466 {
467 return EGL_SUCCESS;
468 }
469
470 ID3D11Device *device = mRenderer->getDevice();
daniel@transgaming.come0970472012-11-28 21:05:07 +0000471 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000472
daniel@transgaming.come0970472012-11-28 21:05:07 +0000473 // Set vertices
474 D3D11_MAPPED_SUBRESOURCE mappedResource;
475 HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
476 if (FAILED(result))
477 {
478 return EGL_BAD_ACCESS;
479 }
480
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +0000481 d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000482
483 // Create a quad in homogeneous coordinates
shannon.woods@transgaming.com2ac02d52013-01-25 21:56:54 +0000484 float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
485 float y1 = ((mHeight - y - height) / float(mHeight)) * 2.0f - 1.0f;
486 float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f;
487 float y2 = ((mHeight - y) / float(mHeight)) * 2.0f - 1.0f;
daniel@transgaming.come0970472012-11-28 21:05:07 +0000488
489 float u1 = x / float(mWidth);
490 float v1 = y / float(mHeight);
491 float u2 = (x + width) / float(mWidth);
492 float v2 = (y + height) / float(mHeight);
493
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +0000494 d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1);
495 d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
496 d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
497 d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000498
499 deviceContext->Unmap(mQuadVB, 0);
500
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +0000501 static UINT stride = sizeof(d3d11::PositionTexCoordVertex);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000502 static UINT startIdx = 0;
503 deviceContext->IASetVertexBuffers(0, 1, &mQuadVB, &stride, &startIdx);
504
505 // Apply state
506 deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
507
508 static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
509 deviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFF);
510
511 deviceContext->RSSetState(NULL);
512
513 // Apply shaders
514 deviceContext->IASetInputLayout(mPassThroughIL);
515 deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
516 deviceContext->VSSetShader(mPassThroughVS, NULL, 0);
517 deviceContext->PSSetShader(mPassThroughPS, NULL, 0);
shannon.woods@transgaming.com3e773bb2013-01-25 21:55:47 +0000518 deviceContext->GSSetShader(NULL, NULL, 0);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000519
520 // Apply render targets
521 deviceContext->OMSetRenderTargets(1, &mBackBufferRTView, NULL);
522
daniel@transgaming.com9799a2f2013-01-11 04:09:27 +0000523 // Set the viewport
524 D3D11_VIEWPORT viewport;
525 viewport.TopLeftX = 0;
526 viewport.TopLeftY = 0;
527 viewport.Width = mWidth;
528 viewport.Height = mHeight;
529 viewport.MinDepth = 0.0f;
530 viewport.MaxDepth = 1.0f;
531 deviceContext->RSSetViewports(1, &viewport);
532
daniel@transgaming.come0970472012-11-28 21:05:07 +0000533 // Apply textures
534 deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView);
535 deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler);
536
537 // Draw
538 deviceContext->Draw(4, 0);
shannon.woods@transgaming.comad74a4b2013-02-28 23:04:09 +0000539 mSwapChain->Present(mSwapInterval, 0);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000540
541 // Unbind
542 static ID3D11ShaderResourceView *const nullSRV = NULL;
543 deviceContext->PSSetShaderResources(0, 1, &nullSRV);
544
545 static ID3D11RenderTargetView *const nullRTV = NULL;
546 deviceContext->OMSetRenderTargets(1, &nullRTV, NULL);
547
daniel@transgaming.come0970472012-11-28 21:05:07 +0000548 mRenderer->markAllStateDirty();
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000549
550 return EGL_SUCCESS;
551}
552
shannon.woods@transgaming.com5c25ed22013-01-25 21:49:51 +0000553// Increments refcount on texture.
554// caller must Release() the returned texture
555ID3D11Texture2D *SwapChain11::getOffscreenTexture()
556{
557 if (mOffscreenTexture)
558 {
559 mOffscreenTexture->AddRef();
560 }
561
562 return mOffscreenTexture;
563}
564
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000565// Increments refcount on view.
566// caller must Release() the returned view
567ID3D11RenderTargetView *SwapChain11::getRenderTarget()
568{
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000569 if (mOffscreenRTView)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000570 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000571 mOffscreenRTView->AddRef();
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000572 }
573
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000574 return mOffscreenRTView;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000575}
576
577// Increments refcount on view.
578// caller must Release() the returned view
shannon.woods@transgaming.com5c25ed22013-01-25 21:49:51 +0000579ID3D11ShaderResourceView *SwapChain11::getRenderTargetShaderResource()
580{
581 if (mOffscreenSRView)
582 {
583 mOffscreenSRView->AddRef();
584 }
585
586 return mOffscreenSRView;
587}
588
589// Increments refcount on view.
590// caller must Release() the returned view
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000591ID3D11DepthStencilView *SwapChain11::getDepthStencil()
592{
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000593 if (mDepthStencilDSView)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000594 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000595 mDepthStencilDSView->AddRef();
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000596 }
597
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000598 return mDepthStencilDSView;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000599}
600
daniel@transgaming.comd733bb82012-11-28 20:53:40 +0000601SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain)
602{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +0000603 ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain11*, swapChain));
daniel@transgaming.comd733bb82012-11-28 20:53:40 +0000604 return static_cast<rx::SwapChain11*>(swapChain);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000605}
daniel@transgaming.comd733bb82012-11-28 20:53:40 +0000606
607}