blob: f3faae44a9e6942f994f95292aca078f5c33c666 [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.comc60c5212013-01-25 21:54:01 +000043 mAppCreatedShareHandle = mShareHandle != NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000044}
45
46SwapChain11::~SwapChain11()
47{
48 release();
49}
50
51void SwapChain11::release()
52{
53 if (mSwapChain)
54 {
55 mSwapChain->Release();
56 mSwapChain = NULL;
57 }
58
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000059 if (mBackBufferTexture)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000060 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000061 mBackBufferTexture->Release();
62 mBackBufferTexture = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000063 }
64
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000065 if (mBackBufferRTView)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000066 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000067 mBackBufferRTView->Release();
68 mBackBufferRTView = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +000069 }
70
71 if (mOffscreenTexture)
72 {
73 mOffscreenTexture->Release();
74 mOffscreenTexture = NULL;
75 }
76
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000077 if (mOffscreenRTView)
78 {
79 mOffscreenRTView->Release();
80 mOffscreenRTView = NULL;
81 }
82
daniel@transgaming.come0970472012-11-28 21:05:07 +000083 if (mOffscreenSRView)
84 {
85 mOffscreenSRView->Release();
86 mOffscreenSRView = NULL;
87 }
88
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +000089 if (mDepthStencilTexture)
90 {
91 mDepthStencilTexture->Release();
92 mDepthStencilTexture = NULL;
93 }
94
95 if (mDepthStencilDSView)
96 {
97 mDepthStencilDSView->Release();
98 mDepthStencilDSView = NULL;
99 }
100
daniel@transgaming.come0970472012-11-28 21:05:07 +0000101 if (mQuadVB)
102 {
103 mQuadVB->Release();
104 mQuadVB = NULL;
105 }
106
107 if (mPassThroughSampler)
108 {
109 mPassThroughSampler->Release();
110 mPassThroughSampler = NULL;
111 }
112
113 if (mPassThroughIL)
114 {
115 mPassThroughIL->Release();
116 mPassThroughIL = NULL;
117 }
118
119 if (mPassThroughVS)
120 {
121 mPassThroughVS->Release();
122 mPassThroughVS = NULL;
123 }
124
125 if (mPassThroughPS)
126 {
127 mPassThroughPS->Release();
128 mPassThroughPS = NULL;
129 }
130
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000131 if (!mAppCreatedShareHandle)
132 {
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000133 mShareHandle = NULL;
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000134 }
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000135}
136
137EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
138{
139 ID3D11Device *device = mRenderer->getDevice();
140
141 if (device == NULL)
142 {
143 return EGL_BAD_ACCESS;
144 }
145
146 // Release specific resources to free up memory for the new render target, while the
147 // old render target still exists for the purpose of preserving its contents.
148 if (mSwapChain)
149 {
150 mSwapChain->Release();
151 mSwapChain = NULL;
152 }
153
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000154 if (mBackBufferTexture)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000155 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000156 mBackBufferTexture->Release();
157 mBackBufferTexture = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000158 }
159
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000160 if (mBackBufferRTView)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000161 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000162 mBackBufferRTView->Release();
163 mBackBufferRTView = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000164 }
165
166 if (mOffscreenTexture)
167 {
168 mOffscreenTexture->Release();
169 mOffscreenTexture = NULL;
170 }
171
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000172 if (mOffscreenRTView) // TODO: Preserve the render target content
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000173 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000174 mOffscreenRTView->Release();
175 mOffscreenRTView = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000176 }
177
daniel@transgaming.come0970472012-11-28 21:05:07 +0000178 if (mOffscreenSRView)
179 {
180 mOffscreenSRView->Release();
181 mOffscreenSRView = NULL;
182 }
183
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000184 if (mDepthStencilTexture)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000185 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000186 mDepthStencilTexture->Release();
187 mDepthStencilTexture = NULL;
188 }
189
190 if (mDepthStencilDSView)
191 {
192 mDepthStencilDSView->Release();
193 mDepthStencilDSView = NULL;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000194 }
195
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000196 // If the app passed in a share handle, open the resource
197 // See EGL_ANGLE_d3d_share_handle_client_buffer
198 if (mAppCreatedShareHandle)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000199 {
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000200 ID3D11Resource *tempResource11;
201 HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000202
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000203 if (FAILED(result))
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000204 {
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000205 ERR("Failed to open the swap chain pbuffer share handle: %08lX", result);
206 release();
207 return EGL_BAD_PARAMETER;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000208 }
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000209
210 result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture);
211 tempResource11->Release();
212
213 if (FAILED(result))
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000214 {
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000215 ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result);
216 release();
217 return EGL_BAD_PARAMETER;
218 }
219
220 // Validate offscreen texture parameters
221 D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
222 mOffscreenTexture->GetDesc(&offscreenTextureDesc);
223
224 if (offscreenTextureDesc.Width != (UINT)backbufferWidth
225 || offscreenTextureDesc.Height != (UINT)backbufferHeight
226 || offscreenTextureDesc.Format != gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat)
227 || offscreenTextureDesc.MipLevels != 1
228 || offscreenTextureDesc.ArraySize != 1)
229 {
230 ERR("Invalid texture parameters in the shared offscreen texture pbuffer");
231 release();
232 return EGL_BAD_PARAMETER;
233 }
234 }
235 else
236 {
237 const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport();
238
239 D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
240 offscreenTextureDesc.Width = backbufferWidth;
241 offscreenTextureDesc.Height = backbufferHeight;
242 offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
243 offscreenTextureDesc.MipLevels = 1;
244 offscreenTextureDesc.ArraySize = 1;
245 offscreenTextureDesc.SampleDesc.Count = 1;
246 offscreenTextureDesc.SampleDesc.Quality = 0;
247 offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
248 offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
249 offscreenTextureDesc.CPUAccessFlags = 0;
250 offscreenTextureDesc.MiscFlags = useSharedResource ? D3D11_RESOURCE_MISC_SHARED : 0;
251
252 HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture);
253
254 if (FAILED(result))
255 {
256 ERR("Could not create offscreen texture: %08lX", result);
257 release();
258
259 if (isDeviceLostError(result))
260 {
261 return EGL_CONTEXT_LOST;
262 }
263 else
264 {
265 return EGL_BAD_ALLOC;
266 }
267 }
268
269 d3d11::SetDebugName(mOffscreenTexture, "Offscreen texture");
270
271 // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client
272 if (useSharedResource)
273 {
274 IDXGIResource *offscreenTextureResource = NULL;
275 result = mOffscreenTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&offscreenTextureResource);
276
277 // Fall back to no share handle on failure
278 if (FAILED(result))
279 {
280 ERR("Could not query offscreen texture resource: %08lX", result);
281 }
282 else
283 {
284 result = offscreenTextureResource->GetSharedHandle(&mShareHandle);
285
286 if (FAILED(result))
287 {
288 mShareHandle = NULL;
289 ERR("Could not get offscreen texture shared handle: %08lX", result);
290 }
291 }
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000292 }
293 }
294
shannon.woods@transgaming.comc60c5212013-01-25 21:54:01 +0000295 HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, NULL, &mOffscreenRTView);
296
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000297 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000298 d3d11::SetDebugName(mOffscreenRTView, "Offscreen render target");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000299
daniel@transgaming.come0970472012-11-28 21:05:07 +0000300 result = device->CreateShaderResourceView(mOffscreenTexture, NULL, &mOffscreenSRView);
301 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000302 d3d11::SetDebugName(mOffscreenSRView, "Offscreen shader resource");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000303
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000304 if (mWindow)
305 {
shannon.woods@transgaming.com7d4b4822013-01-25 21:52:27 +0000306 // We cannot create a swap chain for an HWND that is owned by a different process
307 DWORD currentProcessId = GetCurrentProcessId();
308 DWORD wndProcessId;
309 GetWindowThreadProcessId(mWindow, &wndProcessId);
310
311 if (currentProcessId != wndProcessId)
312 {
313 ERR("Could not create swap chain, window owned by different process");
314 release();
315 return EGL_BAD_NATIVE_WINDOW;
316 }
317
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000318 IDXGIFactory *factory = mRenderer->getDxgiFactory();
319
320 DXGI_SWAP_CHAIN_DESC swapChainDesc = {0};
321 swapChainDesc.BufferCount = 2;
322 swapChainDesc.BufferDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
daniel@transgaming.com567b9cf2012-11-28 21:04:46 +0000323 swapChainDesc.BufferDesc.Width = backbufferWidth;
324 swapChainDesc.BufferDesc.Height = backbufferHeight;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000325 swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
326 swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
327 swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
328 swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
329 swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
330 swapChainDesc.Flags = 0;
331 swapChainDesc.OutputWindow = mWindow;
332 swapChainDesc.SampleDesc.Count = 1;
333 swapChainDesc.SampleDesc.Quality = 0;
334 swapChainDesc.Windowed = TRUE;
335
336 result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
337
338 if (FAILED(result))
339 {
340 ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
341 release();
342
343 if (isDeviceLostError(result))
344 {
345 return EGL_CONTEXT_LOST;
346 }
347 else
348 {
349 return EGL_BAD_ALLOC;
350 }
351 }
352
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000353 result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000354 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000355 d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000356
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000357 result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000358 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000359 d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000360 }
361
362 if (mDepthBufferFormat != GL_NONE)
363 {
364 D3D11_TEXTURE2D_DESC depthStencilDesc = {0};
365 depthStencilDesc.Width = backbufferWidth;
366 depthStencilDesc.Height = backbufferHeight;
367 depthStencilDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mDepthBufferFormat);
368 depthStencilDesc.MipLevels = 1;
369 depthStencilDesc.ArraySize = 1;
370 depthStencilDesc.SampleDesc.Count = 1;
371 depthStencilDesc.SampleDesc.Quality = 0;
372 depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
373 depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
374 depthStencilDesc.CPUAccessFlags = 0;
375 depthStencilDesc.MiscFlags = 0;
376
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000377 result = device->CreateTexture2D(&depthStencilDesc, NULL, &mDepthStencilTexture);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000378 if (FAILED(result))
379 {
380 ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
381 release();
382
383 if (isDeviceLostError(result))
384 {
385 return EGL_CONTEXT_LOST;
386 }
387 else
388 {
389 return EGL_BAD_ALLOC;
390 }
391 }
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000392 d3d11::SetDebugName(mDepthStencilTexture, "Depth stencil texture");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000393
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000394 result = device->CreateDepthStencilView(mDepthStencilTexture, NULL, &mDepthStencilDSView);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000395 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000396 d3d11::SetDebugName(mDepthStencilDSView, "Depth stencil view");
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000397 }
398
daniel@transgaming.come0970472012-11-28 21:05:07 +0000399 D3D11_BUFFER_DESC vbDesc;
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +0000400 vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4;
daniel@transgaming.come0970472012-11-28 21:05:07 +0000401 vbDesc.Usage = D3D11_USAGE_DYNAMIC;
402 vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
403 vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
404 vbDesc.MiscFlags = 0;
405 vbDesc.StructureByteStride = 0;
406
407 result = device->CreateBuffer(&vbDesc, NULL, &mQuadVB);
408 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000409 d3d11::SetDebugName(mQuadVB, "Swap chain quad vertex buffer");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000410
411 D3D11_SAMPLER_DESC samplerDesc;
412 samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
413 samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
414 samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
415 samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
416 samplerDesc.MipLODBias = 0.0f;
417 samplerDesc.MaxAnisotropy = 0;
418 samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
419 samplerDesc.BorderColor[0] = 0.0f;
420 samplerDesc.BorderColor[1] = 0.0f;
421 samplerDesc.BorderColor[2] = 0.0f;
422 samplerDesc.BorderColor[3] = 0.0f;
423 samplerDesc.MinLOD = 0;
424 samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
425
426 result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler);
427 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000428 d3d11::SetDebugName(mPassThroughSampler, "Swap chain pass through sampler");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000429
430 D3D11_INPUT_ELEMENT_DESC quadLayout[] =
431 {
432 { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
433 { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
434 };
435
436 result = device->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mPassThroughIL);
437 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000438 d3d11::SetDebugName(mPassThroughIL, "Swap chain pass through layout");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000439
440 result = device->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mPassThroughVS);
441 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000442 d3d11::SetDebugName(mPassThroughVS, "Swap chain pass through vertex shader");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000443
shannon.woods@transgaming.com2570c342013-01-25 21:50:22 +0000444 result = device->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mPassThroughPS);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000445 ASSERT(SUCCEEDED(result));
daniel@transgaming.comad3d8272013-01-11 04:11:14 +0000446 d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader");
daniel@transgaming.come0970472012-11-28 21:05:07 +0000447
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000448 mWidth = backbufferWidth;
449 mHeight = backbufferHeight;
450
451 return EGL_SUCCESS;
452}
453
454// parameters should be validated/clamped by caller
455EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
456{
457 if (!mSwapChain)
458 {
459 return EGL_SUCCESS;
460 }
461
462 ID3D11Device *device = mRenderer->getDevice();
daniel@transgaming.come0970472012-11-28 21:05:07 +0000463 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000464
daniel@transgaming.come0970472012-11-28 21:05:07 +0000465 // Set vertices
466 D3D11_MAPPED_SUBRESOURCE mappedResource;
467 HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
468 if (FAILED(result))
469 {
470 return EGL_BAD_ACCESS;
471 }
472
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +0000473 d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000474
475 // Create a quad in homogeneous coordinates
476 float x1 = (x / mWidth) * 2.0f - 1.0f;
477 float y1 = ((mHeight - y - height) / mHeight) * 2.0f - 1.0f;
478 float x2 = ((x + width) / mWidth) * 2.0f - 1.0f;
479 float y2 = ((mHeight - y) / mHeight) * 2.0f - 1.0f;
480
481 float u1 = x / float(mWidth);
482 float v1 = y / float(mHeight);
483 float u2 = (x + width) / float(mWidth);
484 float v2 = (y + height) / float(mHeight);
485
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +0000486 d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1);
487 d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
488 d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
489 d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000490
491 deviceContext->Unmap(mQuadVB, 0);
492
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +0000493 static UINT stride = sizeof(d3d11::PositionTexCoordVertex);
daniel@transgaming.come0970472012-11-28 21:05:07 +0000494 static UINT startIdx = 0;
495 deviceContext->IASetVertexBuffers(0, 1, &mQuadVB, &stride, &startIdx);
496
497 // Apply state
498 deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
499
500 static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
501 deviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFF);
502
503 deviceContext->RSSetState(NULL);
504
505 // Apply shaders
506 deviceContext->IASetInputLayout(mPassThroughIL);
507 deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
508 deviceContext->VSSetShader(mPassThroughVS, NULL, 0);
509 deviceContext->PSSetShader(mPassThroughPS, NULL, 0);
510
511 // Apply render targets
512 deviceContext->OMSetRenderTargets(1, &mBackBufferRTView, NULL);
513
daniel@transgaming.com9799a2f2013-01-11 04:09:27 +0000514 // Set the viewport
515 D3D11_VIEWPORT viewport;
516 viewport.TopLeftX = 0;
517 viewport.TopLeftY = 0;
518 viewport.Width = mWidth;
519 viewport.Height = mHeight;
520 viewport.MinDepth = 0.0f;
521 viewport.MaxDepth = 1.0f;
522 deviceContext->RSSetViewports(1, &viewport);
523
daniel@transgaming.come0970472012-11-28 21:05:07 +0000524 // Apply textures
525 deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView);
526 deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler);
527
528 // Draw
529 deviceContext->Draw(4, 0);
530 mSwapChain->Present(0, 0);
531
532 // Unbind
533 static ID3D11ShaderResourceView *const nullSRV = NULL;
534 deviceContext->PSSetShaderResources(0, 1, &nullSRV);
535
536 static ID3D11RenderTargetView *const nullRTV = NULL;
537 deviceContext->OMSetRenderTargets(1, &nullRTV, NULL);
538
daniel@transgaming.come0970472012-11-28 21:05:07 +0000539 mRenderer->markAllStateDirty();
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000540
541 return EGL_SUCCESS;
542}
543
shannon.woods@transgaming.com5c25ed22013-01-25 21:49:51 +0000544// Increments refcount on texture.
545// caller must Release() the returned texture
546ID3D11Texture2D *SwapChain11::getOffscreenTexture()
547{
548 if (mOffscreenTexture)
549 {
550 mOffscreenTexture->AddRef();
551 }
552
553 return mOffscreenTexture;
554}
555
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000556// Increments refcount on view.
557// caller must Release() the returned view
558ID3D11RenderTargetView *SwapChain11::getRenderTarget()
559{
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000560 if (mOffscreenRTView)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000561 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000562 mOffscreenRTView->AddRef();
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000563 }
564
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000565 return mOffscreenRTView;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000566}
567
568// Increments refcount on view.
569// caller must Release() the returned view
shannon.woods@transgaming.com5c25ed22013-01-25 21:49:51 +0000570ID3D11ShaderResourceView *SwapChain11::getRenderTargetShaderResource()
571{
572 if (mOffscreenSRView)
573 {
574 mOffscreenSRView->AddRef();
575 }
576
577 return mOffscreenSRView;
578}
579
580// Increments refcount on view.
581// caller must Release() the returned view
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000582ID3D11DepthStencilView *SwapChain11::getDepthStencil()
583{
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000584 if (mDepthStencilDSView)
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000585 {
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000586 mDepthStencilDSView->AddRef();
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000587 }
588
daniel@transgaming.comc8c70ad2012-11-28 21:04:37 +0000589 return mDepthStencilDSView;
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000590}
591
daniel@transgaming.comd733bb82012-11-28 20:53:40 +0000592SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain)
593{
594 ASSERT(dynamic_cast<rx::SwapChain11*>(swapChain) != NULL);
595 return static_cast<rx::SwapChain11*>(swapChain);
daniel@transgaming.com32fdf822012-11-28 20:53:30 +0000596}
daniel@transgaming.comd733bb82012-11-28 20:53:40 +0000597
598}