1bdf2d80f459d43f5a6df074431bacf41584f81b7shannon.woods@transgaming.com#include "precompiled.h"
21d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com//
3eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
41d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be
51d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com// found in the LICENSE file.
61d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com//
71d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
81d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com// Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
91d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
105503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com#include "libGLESv2/main.h"
11a2ecfcccf1d1a85e6054a7314ce1f9de0648ac7fshannonwoods@chromium.org#include "common/utilities.h"
1218adad0cdbb1e29ef9df98162555cac413b2ac0fdaniel@transgaming.com#include "libGLESv2/Buffer.h"
135367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com#include "libGLESv2/ProgramBinary.h"
1480fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com#include "libGLESv2/Framebuffer.h"
15486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libGLESv2/RenderBuffer.h"
16d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/Renderer11.h"
17d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/RenderTarget11.h"
18d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/renderer11_utils.h"
19d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/formatutils11.h"
20d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/ShaderExecutable11.h"
21d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/SwapChain11.h"
22d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/Image11.h"
23d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/VertexBuffer11.h"
24d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/IndexBuffer11.h"
25d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/BufferStorage11.h"
26c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com#include "libGLESv2/renderer/VertexDataManager.h"
27c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com#include "libGLESv2/renderer/IndexDataManager.h"
28d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/TextureStorage11.h"
29d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/Query11.h"
30d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/Fence11.h"
31d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/Blit11.h"
32d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/Clear11.h"
33d47e0fcc28925847ac0d7f9bfd9b7d8660700345Geoff Lang#include "libGLESv2/renderer/d3d11/PixelTransfer11.h"
34486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libEGL/Display.h"
35486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com
3694a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang// Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process
3794a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang// HWNDs or the Windows 7 Platform Update (KB2670838) is expected to be installed.
3894a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang#ifndef ANGLE_SKIP_DXGI_1_2_CHECK
3994a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang#define ANGLE_SKIP_DXGI_1_2_CHECK 0
4094a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang#endif
4194a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang
42236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com#ifdef _DEBUG
43236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com// this flag enables suppressing some spurious warnings that pop up in certain WebGL samples
44236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com// and conformance tests. to enable all warnings, remove this define.
45236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com#define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1
46236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com#endif
47236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com
481d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comnamespace rx
491d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
5065e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.comstatic const DXGI_FORMAT RenderTargetFormats[] =
5165e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    {
52c60c5215ebab426654d1670282d15652667e38dashannon.woods@transgaming.com        DXGI_FORMAT_B8G8R8A8_UNORM,
5365e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com        DXGI_FORMAT_R8G8B8A8_UNORM
5465e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    };
5565e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
5665e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.comstatic const DXGI_FORMAT DepthStencilFormats[] =
5765e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    {
58eec5c6308990a157ee3fe0f66349ebc3cee3fc19shannon.woods@transgaming.com        DXGI_FORMAT_UNKNOWN,
59eec5c6308990a157ee3fe0f66349ebc3cee3fc19shannon.woods@transgaming.com        DXGI_FORMAT_D24_UNORM_S8_UINT,
60eec5c6308990a157ee3fe0f66349ebc3cee3fc19shannon.woods@transgaming.com        DXGI_FORMAT_D16_UNORM
6165e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    };
621d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
63233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.comenum
64233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com{
65233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com    MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
66233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com};
67233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com
681d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comRenderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
691d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
70c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    mVertexDataManager = NULL;
71c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    mIndexDataManager = NULL;
72c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com
73c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    mLineLoopIB = NULL;
744fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    mTriangleFanIB = NULL;
75c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com
76b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    mBlit = NULL;
77a21eea36fbb03d7d680ca7f472fcf96b1bbc1f63Jamie Madill    mPixelTransfer = NULL;
789d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
79da507fea063b882095bd54753cabc685ffdb575dGeoff Lang    mClear = NULL;
8034f507ce49938eb1f3cd9e2780ea53a72795a20ashannon.woods@transgaming.com
81bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com    mSyncQuery = NULL;
82bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com
831d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    mD3d11Module = NULL;
841d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    mDxgiModule = NULL;
851d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
86b9bb27938fae86822453d7cba1bba6c704000a8adaniel@transgaming.com    mDeviceLost = false;
87b9bb27938fae86822453d7cba1bba6c704000a8adaniel@transgaming.com
88df2fd572d419751477490fef10db8608e5d73545shannon.woods@transgaming.com    mMaxSupportedSamples = 0;
89df2fd572d419751477490fef10db8608e5d73545shannon.woods@transgaming.com
9025072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    mDevice = NULL;
911d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    mDeviceContext = NULL;
9265e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    mDxgiAdapter = NULL;
9365e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    mDxgiFactory = NULL;
945fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com
955fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    mDriverConstantBufferVS = NULL;
965fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    mDriverConstantBufferPS = NULL;
97bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com
98bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com    mBGRATextureSupport = false;
99dd2524c46ed4689c27adf3f9959435fd2906b621shannon.woods@transgaming.com
1006246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    mAppliedVertexShader = NULL;
1016246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    mAppliedGeometryShader = NULL;
1024c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    mCurPointGeometryShader = NULL;
1036246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    mAppliedPixelShader = NULL;
1041d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
1051d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
1061d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comRenderer11::~Renderer11()
1071d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
108ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    release();
1091d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
1101d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
111b64ed2824bfd5d67acb415300427edc40ae79253daniel@transgaming.comRenderer11 *Renderer11::makeRenderer11(Renderer *renderer)
112b64ed2824bfd5d67acb415300427edc40ae79253daniel@transgaming.com{
1138b400b1e8d84c5b93dd151807504a3e4b90d1b21apatrick@chromium.org    ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer11*, renderer));
114b64ed2824bfd5d67acb415300427edc40ae79253daniel@transgaming.com    return static_cast<rx::Renderer11*>(renderer);
115b64ed2824bfd5d67acb415300427edc40ae79253daniel@transgaming.com}
116b64ed2824bfd5d67acb415300427edc40ae79253daniel@transgaming.com
117f9686c219a99254e8425cb9253651754f597796bshannon.woods%transgaming.com@gtempaccount.com#ifndef __d3d11_1_h__
118f9686c219a99254e8425cb9253651754f597796bshannon.woods%transgaming.com@gtempaccount.com#define D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET ((D3D11_MESSAGE_ID)3146081)
119f9686c219a99254e8425cb9253651754f597796bshannon.woods%transgaming.com@gtempaccount.com#endif
120f9686c219a99254e8425cb9253651754f597796bshannon.woods%transgaming.com@gtempaccount.com
1211d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comEGLint Renderer11::initialize()
1221d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
123dad5ed3953e4f31c35b9fd67901fb78dbe140dd0Geoff Lang    if (!mCompiler.initialize())
12425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com    {
12525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com        return EGL_NOT_INITIALIZED;
12625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com    }
12725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com
128c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com    mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
129c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com    mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
1301d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
1311d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    if (mD3d11Module == NULL || mDxgiModule == NULL)
1321d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    {
133c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com        ERR("Could not load D3D11 or DXGI library - aborting!\n");
1341d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com        return EGL_NOT_INITIALIZED;
1351d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    }
1361d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
137ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    // create the D3D11 device
138ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    ASSERT(mDevice == NULL);
139c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com    PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
140c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com
141c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com    if (D3D11CreateDevice == NULL)
142c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com    {
143c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com        ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
144c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com        return EGL_NOT_INITIALIZED;
145c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com    }
146df2fd572d419751477490fef10db8608e5d73545shannon.woods@transgaming.com
147d438fd497baeddedec135e7c8bfa4148e116b9a8shannon.woods@transgaming.com    D3D_FEATURE_LEVEL featureLevels[] =
14825072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    {
14925072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com        D3D_FEATURE_LEVEL_11_0,
15025072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com        D3D_FEATURE_LEVEL_10_1,
15125072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com        D3D_FEATURE_LEVEL_10_0,
15225072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    };
153df2fd572d419751477490fef10db8608e5d73545shannon.woods@transgaming.com
154c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org    HRESULT result = S_OK;
155c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org
156c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org#ifdef _DEBUG
157c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org    result = D3D11CreateDevice(NULL,
158c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                               D3D_DRIVER_TYPE_HARDWARE,
159c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                               NULL,
160c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                               D3D11_CREATE_DEVICE_DEBUG,
161c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                               featureLevels,
162c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                               ArraySize(featureLevels),
163c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                               D3D11_SDK_VERSION,
164c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                               &mDevice,
165c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                               &mFeatureLevel,
166c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                               &mDeviceContext);
167df2fd572d419751477490fef10db8608e5d73545shannon.woods@transgaming.com
16825072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    if (!mDevice || FAILED(result))
169c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com    {
170c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org        ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n");
171c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org    }
172c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org
173c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org    if (!mDevice || FAILED(result))
174c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org#endif
175c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org    {
176c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org        result = D3D11CreateDevice(NULL,
177c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                                   D3D_DRIVER_TYPE_HARDWARE,
178c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                                   NULL,
179c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                                   0,
180c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                                   featureLevels,
181c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                                   ArraySize(featureLevels),
182c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                                   D3D11_SDK_VERSION,
183c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                                   &mDevice,
184c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                                   &mFeatureLevel,
185c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org                                   &mDeviceContext);
186c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org
187c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org        if (!mDevice || FAILED(result))
188c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org        {
189c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org            ERR("Could not create D3D11 device - aborting!\n");
190c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org            return EGL_NOT_INITIALIZED;   // Cleanup done by destructor through glDestroyRenderer
191c3419c102cafbad6fbf4bb91e6ace22292ebd093shannonwoods@chromium.org        }
192c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com    }
19365e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
19494a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang#if !ANGLE_SKIP_DXGI_1_2_CHECK
19594a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required.
19694a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    // The easiest way to check is to query for a IDXGIDevice2.
19794a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    bool requireDXGI1_2 = false;
19894a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    HWND hwnd = WindowFromDC(mDc);
19994a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    if (hwnd)
20094a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    {
20194a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang        DWORD currentProcessId = GetCurrentProcessId();
20294a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang        DWORD wndProcessId;
20394a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang        GetWindowThreadProcessId(hwnd, &wndProcessId);
20494a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang        requireDXGI1_2 = (currentProcessId != wndProcessId);
20594a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    }
20694a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    else
20794a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    {
20894a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang        requireDXGI1_2 = true;
20994a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    }
21094a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang
21194a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    if (requireDXGI1_2)
21294a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    {
21394a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang        IDXGIDevice2 *dxgiDevice2 = NULL;
21494a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang        result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void**)&dxgiDevice2);
21594a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang        if (FAILED(result))
21694a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang        {
21794a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang            ERR("DXGI 1.2 required to present to HWNDs owned by another process.\n");
21894a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang            return EGL_NOT_INITIALIZED;
21994a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang        }
22094a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang        SafeRelease(dxgiDevice2);
22194a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang    }
22294a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang#endif
22394a9089bbb6224bf6c7c392fbde855823dac342dGeoff Lang
22465e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    IDXGIDevice *dxgiDevice = NULL;
22565e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
22665e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
22765e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    if (FAILED(result))
22865e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    {
22965e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com        ERR("Could not query DXGI device - aborting!\n");
23065e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com        return EGL_NOT_INITIALIZED;
23165e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    }
23265e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
23365e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
23465e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
23565e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    if (FAILED(result))
23665e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    {
23765e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com        ERR("Could not retrieve DXGI adapter - aborting!\n");
23865e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com        return EGL_NOT_INITIALIZED;
23965e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    }
24065e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
241ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(dxgiDevice);
24265e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
2431f811f55df504216a4d6c5e0921110639f138ac9daniel@transgaming.com    mDxgiAdapter->GetDesc(&mAdapterDescription);
2441f811f55df504216a4d6c5e0921110639f138ac9daniel@transgaming.com    memset(mDescription, 0, sizeof(mDescription));
2451f811f55df504216a4d6c5e0921110639f138ac9daniel@transgaming.com    wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
2461f811f55df504216a4d6c5e0921110639f138ac9daniel@transgaming.com
24765e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
24865e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
24965e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    if (!mDxgiFactory || FAILED(result))
25065e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    {
25165e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com        ERR("Could not create DXGI factory - aborting!\n");
25265e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com        return EGL_NOT_INITIALIZED;
25365e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    }
25465e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
255236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com    // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
256236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
257236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com    ID3D11InfoQueue *infoQueue;
258236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com    result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue),  (void **)&infoQueue);
259236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com
260236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com    if (SUCCEEDED(result))
261236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com    {
262236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com        D3D11_MESSAGE_ID hideMessages[] =
263236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com        {
264f9686c219a99254e8425cb9253651754f597796bshannon.woods%transgaming.com@gtempaccount.com            D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET
265236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com        };
266236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com
267236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com        D3D11_INFO_QUEUE_FILTER filter = {0};
268236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com        filter.DenyList.NumIDs = ArraySize(hideMessages);
269236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com        filter.DenyList.pIDList = hideMessages;
270236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com
271236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com        infoQueue->AddStorageFilterEntries(&filter);
272ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(infoQueue);
273236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com    }
274236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com#endif
275236be77d911359106fca6014aa97a340fcea3c30shannon.woods@transgaming.com
27661e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang    mMaxSupportedSamples = 0;
277df2fd572d419751477490fef10db8608e5d73545shannon.woods@transgaming.com
27861e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang    const d3d11::DXGIFormatSet &dxgiFormats = d3d11::GetAllUsedDXGIFormats();
27961e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang    for (d3d11::DXGIFormatSet::const_iterator i = dxgiFormats.begin(); i != dxgiFormats.end(); ++i)
28061e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang    {
28161e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang        MultisampleSupportInfo support = getMultisampleSupportInfo(*i);
28261e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang        mMultisampleSupportMap.insert(std::make_pair(*i, support));
28361e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang        mMaxSupportedSamples = std::max(mMaxSupportedSamples, support.maxSupportedSamples);
284df2fd572d419751477490fef10db8608e5d73545shannon.woods@transgaming.com    }
285df2fd572d419751477490fef10db8608e5d73545shannon.woods@transgaming.com
2861d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    initializeDevice();
2871d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
288bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com    // BGRA texture support is optional in feature levels 10 and 10_1
289bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com    UINT formatSupport;
290bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com    result = mDevice->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &formatSupport);
291bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com    if (FAILED(result))
292bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com    {
293bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com        ERR("Error checking BGRA format support: 0x%08X", result);
294bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com    }
295bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com    else
296bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com    {
297bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com        const int flags = (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET);
298bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com        mBGRATextureSupport = (formatSupport & flags) == flags;
299bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com    }
300bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com
3019cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    // Check floating point texture support
3029cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    static const unsigned int requiredTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE;
3039cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    static const unsigned int requiredRenderableFlags = D3D11_FORMAT_SUPPORT_RENDER_TARGET;
3049cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    static const unsigned int requiredFilterFlags = D3D11_FORMAT_SUPPORT_SHADER_SAMPLE;
3059cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com
3069cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    DXGI_FORMAT float16Formats[] =
3079cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    {
3089cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        DXGI_FORMAT_R16_FLOAT,
3099cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        DXGI_FORMAT_R16G16_FLOAT,
3109cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        DXGI_FORMAT_R16G16B16A16_FLOAT,
3119cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    };
3129cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com
3139cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    DXGI_FORMAT float32Formats[] =
3149cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    {
3159cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        DXGI_FORMAT_R32_FLOAT,
3169cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        DXGI_FORMAT_R32G32_FLOAT,
3179cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        DXGI_FORMAT_R32G32B32A32_FLOAT,
3189cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    };
3199cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com
3209cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    mFloat16TextureSupport = true;
3219cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    mFloat16FilterSupport = true;
3229cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    mFloat16RenderSupport = true;
3239cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    for (unsigned int i = 0; i < ArraySize(float16Formats); i++)
3249cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    {
3259cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        if (SUCCEEDED(mDevice->CheckFormatSupport(float16Formats[i], &formatSupport)))
3269cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        {
3279cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com            mFloat16TextureSupport = mFloat16TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
3289cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com            mFloat16FilterSupport = mFloat16FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
3299cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com            mFloat16RenderSupport = mFloat16RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
3309cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        }
3319cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        else
3329cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        {
3339cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com            mFloat16TextureSupport = false;
3349cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com            mFloat16RenderSupport = false;
3359cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com            mFloat16FilterSupport = false;
3369cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        }
3379cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    }
3389cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com
3399cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    mFloat32TextureSupport = true;
3409cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    mFloat32FilterSupport = true;
3419cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    mFloat32RenderSupport = true;
3429cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    for (unsigned int i = 0; i < ArraySize(float32Formats); i++)
3439cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    {
3449cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        if (SUCCEEDED(mDevice->CheckFormatSupport(float32Formats[i], &formatSupport)))
3459cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        {
3469cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com            mFloat32TextureSupport = mFloat32TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
3479cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com            mFloat32FilterSupport = mFloat32FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
3489cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com            mFloat32RenderSupport = mFloat32RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
3499cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        }
3509cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        else
3519cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        {
3529cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com            mFloat32TextureSupport = false;
3539cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com            mFloat32FilterSupport = false;
3549cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com            mFloat32RenderSupport = false;
3559cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com        }
3569cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    }
3579cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com
358632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang    DXGI_FORMAT rgTextureFormats[] =
359632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang    {
360632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang        DXGI_FORMAT_R8_UNORM,
361632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang        DXGI_FORMAT_R8G8_UNORM,
362632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang        DXGI_FORMAT_R16_FLOAT,
363632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang        DXGI_FORMAT_R16G16_FLOAT,
364632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang        DXGI_FORMAT_R32_FLOAT,
365632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang        DXGI_FORMAT_R32G32_FLOAT,
366632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang    };
367632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang
368632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang    mRGTextureSupport = true;
369632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang    for (unsigned int i = 0; i < ArraySize(rgTextureFormats); i++)
370632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang    {
371632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang        if (SUCCEEDED(mDevice->CheckFormatSupport(rgTextureFormats[i], &formatSupport)))
372632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang        {
373632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang            mRGTextureSupport = mRGTextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
374632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang            mRGTextureSupport = mRGTextureSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
375632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang            mRGTextureSupport = mRGTextureSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
376632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang        }
377632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang        else
378632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang        {
379632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang            mRGTextureSupport = false;
380632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang        }
381632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang    }
382632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang
38309f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    // Check compressed texture support
38409f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    const unsigned int requiredCompressedTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D;
38509f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com
38609f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &formatSupport)))
38709f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    {
38809f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com        mDXT1TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
38909f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    }
39009f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    else
39109f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    {
39209f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com        mDXT1TextureSupport = false;
39309f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    }
39409f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com
39509f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC3_UNORM, &formatSupport)))
39609f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    {
39709f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com        mDXT3TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
39809f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    }
39909f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    else
40009f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    {
40109f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com        mDXT3TextureSupport = false;
40209f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    }
40309f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com
40409f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC5_UNORM, &formatSupport)))
40509f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    {
40609f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com        mDXT5TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
40709f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    }
40809f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    else
40909f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    {
41009f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com        mDXT5TextureSupport = false;
41109f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    }
41209f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com
413cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com    // Check depth texture support
414cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com    DXGI_FORMAT depthTextureFormats[] =
415cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com    {
416cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com        DXGI_FORMAT_D16_UNORM,
417cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com        DXGI_FORMAT_D24_UNORM_S8_UINT,
418cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com    };
419cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com
420cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com    static const unsigned int requiredDepthTextureFlags = D3D11_FORMAT_SUPPORT_DEPTH_STENCIL |
421cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com                                                          D3D11_FORMAT_SUPPORT_TEXTURE2D;
422cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com
423cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com    mDepthTextureSupport = true;
424cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com    for (unsigned int i = 0; i < ArraySize(depthTextureFormats); i++)
425cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com    {
426cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com        if (SUCCEEDED(mDevice->CheckFormatSupport(depthTextureFormats[i], &formatSupport)))
427cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com        {
428cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com            mDepthTextureSupport = mDepthTextureSupport && ((formatSupport & requiredDepthTextureFlags) == requiredDepthTextureFlags);
429cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com        }
430cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com        else
431cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com        {
432cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com            mDepthTextureSupport = false;
433cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com        }
434cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com    }
435cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com
4361d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    return EGL_SUCCESS;
4371d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
4381d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
4391d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com// do any one-time device initialization
4401d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com// NOTE: this is also needed after a device lost/reset
4411d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com// to reset the scene status and ensure the default states are reset.
4421d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comvoid Renderer11::initializeDevice()
4431d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
444f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com    mStateCache.initialize(mDevice);
445c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    mInputLayoutCache.initialize(mDevice, mDeviceContext);
446f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com
447c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    ASSERT(!mVertexDataManager && !mIndexDataManager);
448c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    mVertexDataManager = new VertexDataManager(this);
449c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    mIndexDataManager = new IndexDataManager(this);
450c43a60557d5e25cfb80cb0cd3c2a01920251745fdaniel@transgaming.com
451b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    ASSERT(!mBlit);
452b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    mBlit = new Blit11(this);
453b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
454da507fea063b882095bd54753cabc685ffdb575dGeoff Lang    ASSERT(!mClear);
455da507fea063b882095bd54753cabc685ffdb575dGeoff Lang    mClear = new Clear11(this);
456da507fea063b882095bd54753cabc685ffdb575dGeoff Lang
457a21eea36fbb03d7d680ca7f472fcf96b1bbc1f63Jamie Madill    ASSERT(!mPixelTransfer);
458a21eea36fbb03d7d680ca7f472fcf96b1bbc1f63Jamie Madill    mPixelTransfer = new PixelTransfer11(this);
459a21eea36fbb03d7d680ca7f472fcf96b1bbc1f63Jamie Madill
460c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    markAllStateDirty();
4611d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
4621d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
4631d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comint Renderer11::generateConfigs(ConfigDesc **configDescList)
4641d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
465d438fd497baeddedec135e7c8bfa4148e116b9a8shannon.woods@transgaming.com    unsigned int numRenderFormats = ArraySize(RenderTargetFormats);
466d438fd497baeddedec135e7c8bfa4148e116b9a8shannon.woods@transgaming.com    unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
46765e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
46865e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    int numConfigs = 0;
46965e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
470e3e826d41523af95e7bcb2aa3488537746ebf301daniel@transgaming.com    for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
47165e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    {
472e3e826d41523af95e7bcb2aa3488537746ebf301daniel@transgaming.com        for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
47365e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com        {
47465e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com            DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
47565e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
47665e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com            UINT formatSupport = 0;
47765e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com            HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
478df2fd572d419751477490fef10db8608e5d73545shannon.woods@transgaming.com
47965e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com            if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
48065e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com            {
48165e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com                DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
48265e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
483eec5c6308990a157ee3fe0f66349ebc3cee3fc19shannon.woods@transgaming.com                bool depthStencilFormatOK = true;
48465e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
485eec5c6308990a157ee3fe0f66349ebc3cee3fc19shannon.woods@transgaming.com                if (depthStencilFormat != DXGI_FORMAT_UNKNOWN)
486eec5c6308990a157ee3fe0f66349ebc3cee3fc19shannon.woods@transgaming.com                {
4875c9a29abb49d834262712aa461b8ecbfccf0c842Geoff Lang                    UINT depthStencilSupport = 0;
4885c9a29abb49d834262712aa461b8ecbfccf0c842Geoff Lang                    result = mDevice->CheckFormatSupport(depthStencilFormat, &depthStencilSupport);
4895c9a29abb49d834262712aa461b8ecbfccf0c842Geoff Lang                    depthStencilFormatOK = SUCCEEDED(result) && (depthStencilSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL);
490eec5c6308990a157ee3fe0f66349ebc3cee3fc19shannon.woods@transgaming.com                }
491eec5c6308990a157ee3fe0f66349ebc3cee3fc19shannon.woods@transgaming.com
492eec5c6308990a157ee3fe0f66349ebc3cee3fc19shannon.woods@transgaming.com                if (depthStencilFormatOK)
49365e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com                {
494d6cb2443a9805314d214dd448835ea6a58fc8c7dJamie Madill                    // FIXME: parse types from context version
495d6cb2443a9805314d214dd448835ea6a58fc8c7dJamie Madill                    ASSERT(d3d11_gl::GetInternalFormat(renderTargetFormat, 2) == d3d11_gl::GetInternalFormat(renderTargetFormat, 3));
496d6cb2443a9805314d214dd448835ea6a58fc8c7dJamie Madill                    ASSERT(d3d11_gl::GetInternalFormat(depthStencilFormat, 2) == d3d11_gl::GetInternalFormat(depthStencilFormat, 3));
497d6cb2443a9805314d214dd448835ea6a58fc8c7dJamie Madill
49865e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com                    ConfigDesc newConfig;
499d6cb2443a9805314d214dd448835ea6a58fc8c7dJamie Madill                    newConfig.renderTargetFormat = d3d11_gl::GetInternalFormat(renderTargetFormat, getCurrentClientVersion());
500d6cb2443a9805314d214dd448835ea6a58fc8c7dJamie Madill                    newConfig.depthStencilFormat = d3d11_gl::GetInternalFormat(depthStencilFormat, getCurrentClientVersion());
50165e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com                    newConfig.multiSample = 0;     // FIXME: enumerate multi-sampling
50265e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com                    newConfig.fastConfig = true;   // Assume all DX11 format conversions to be fast
503dcf33d53a4b37acb5080f3d681e5bb69da88be60shannon.woods%transgaming.com@gtempaccount.com                    newConfig.es3Capable = true;
50465e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
50565e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com                    (*configDescList)[numConfigs++] = newConfig;
50665e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com                }
50765e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com            }
50865e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com        }
50965e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    }
51065e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com
51165e653778bb96bcb8843fc86df0b9981450a9afddaniel@transgaming.com    return numConfigs;
5121d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
5131d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
5141d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comvoid Renderer11::deleteConfigs(ConfigDesc *configDescList)
5151d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
5161d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    delete [] (configDescList);
5171d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
5181d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
5191d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comvoid Renderer11::sync(bool block)
5201d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
521bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com    if (block)
522bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com    {
523bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com        HRESULT result;
524bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com
525bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com        if (!mSyncQuery)
526bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com        {
527bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com            D3D11_QUERY_DESC queryDesc;
528bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com            queryDesc.Query = D3D11_QUERY_EVENT;
529bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com            queryDesc.MiscFlags = 0;
530bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com
531bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com            result = mDevice->CreateQuery(&queryDesc, &mSyncQuery);
532bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com            ASSERT(SUCCEEDED(result));
533bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com        }
534bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com
535bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com        mDeviceContext->End(mSyncQuery);
536bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com        mDeviceContext->Flush();
537bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com
538bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com        do
539bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com        {
540bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com            result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
541bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com
542bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com            // Keep polling, but allow other threads to do something useful first
543bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com            Sleep(0);
544bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com
545bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com            if (testDeviceLost(true))
546bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com            {
547bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com                return;
548bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com            }
549bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com        }
550bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com        while (result == S_FALSE);
551bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com    }
552bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com    else
553bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com    {
554bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com        mDeviceContext->Flush();
555bdf787fcd74c684f3374bbb4dc7c3e18e38996cadaniel@transgaming.com    }
5561d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
5571d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
558b9bb27938fae86822453d7cba1bba6c704000a8adaniel@transgaming.comSwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
559b9bb27938fae86822453d7cba1bba6c704000a8adaniel@transgaming.com{
560a60160b0c85ea5030edea66590e1475bed8c9a7cdaniel@transgaming.com    return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
561b9bb27938fae86822453d7cba1bba6c704000a8adaniel@transgaming.com}
562b9bb27938fae86822453d7cba1bba6c704000a8adaniel@transgaming.com
563e2e0ce0cd1b4b1845c5df4fc87d75b36ef6a8d6cGeoff Langvoid Renderer11::generateSwizzle(gl::Texture *texture)
564e2e0ce0cd1b4b1845c5df4fc87d75b36ef6a8d6cGeoff Lang{
56542477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    if (texture)
56642477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    {
56742477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        TextureStorageInterface *texStorage = texture->getNativeTexture();
56842477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        if (texStorage)
56942477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        {
57042477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang            TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance());
57142477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
57242477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang            storage11->generateSwizzles(texture->getSwizzleRed(), texture->getSwizzleGreen(), texture->getSwizzleBlue(),
57342477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang                                        texture->getSwizzleAlpha());
57442477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        }
57542477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    }
576e2e0ce0cd1b4b1845c5df4fc87d75b36ef6a8d6cGeoff Lang}
577e2e0ce0cd1b4b1845c5df4fc87d75b36ef6a8d6cGeoff Lang
5781d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comvoid Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
5791d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
58054de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com    if (type == gl::SAMPLER_PIXEL)
58154de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com    {
58254de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS)
58354de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        {
58454de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            ERR("Pixel shader sampler index %i is not valid.", index);
58554de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            return;
58654de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        }
58754de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com
58854de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
58954de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        {
59054de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState);
59154de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com
59254de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            if (!dxSamplerState)
59354de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            {
59454de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com                ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default"
59554de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com                    "sampler state for pixel shaders at slot %i.", index);
59654de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            }
59754de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com
59854de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState);
59954de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com
60054de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            mCurPixelSamplerStates[index] = samplerState;
60154de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        }
60254de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com
60354de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        mForceSetPixelSamplerStates[index] = false;
60454de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com    }
60554de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com    else if (type == gl::SAMPLER_VERTEX)
60654de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com    {
607233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com        if (index < 0 || index >= (int)getMaxVertexTextureImageUnits())
60854de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        {
60954de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            ERR("Vertex shader sampler index %i is not valid.", index);
61054de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            return;
61154de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        }
61254de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com
61354de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
61454de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        {
61554de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState);
61654de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com
61754de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            if (!dxSamplerState)
61854de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            {
61954de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com                ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default"
62054de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com                    "sampler state for vertex shaders at slot %i.", index);
62154de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            }
62254de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com
62354de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState);
62454de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com
62554de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com            mCurVertexSamplerStates[index] = samplerState;
62654de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        }
62754de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com
62854de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        mForceSetVertexSamplerStates[index] = false;
62954de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com    }
63054de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com    else UNREACHABLE();
6311d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
6321d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
6331d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comvoid Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
6341d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
6350785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com    ID3D11ShaderResourceView *textureSRV = NULL;
636e33c8bfa0799f8dcd74a0ac88aacd4247f302386daniel@transgaming.com    bool forceSetTexture = false;
6370785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com
6380785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com    if (texture)
6390785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com    {
6400785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com        TextureStorageInterface *texStorage = texture->getNativeTexture();
6410785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com        if (texStorage)
6420785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com        {
6430785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com            TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance());
644a10c1c7e961a01faa06100785df77801ac0669a3Nicolas Capens            gl::SamplerState samplerState;
645a10c1c7e961a01faa06100785df77801ac0669a3Nicolas Capens            texture->getSamplerState(&samplerState);
646a10c1c7e961a01faa06100785df77801ac0669a3Nicolas Capens            textureSRV = storage11->getSRV(samplerState);
6470785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com        }
6480785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com
6490785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com        // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly
6500785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com        // missing the shader resource view
6510785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com        ASSERT(textureSRV != NULL);
652e33c8bfa0799f8dcd74a0ac88aacd4247f302386daniel@transgaming.com
653e33c8bfa0799f8dcd74a0ac88aacd4247f302386daniel@transgaming.com        forceSetTexture = texture->hasDirtyImages();
6540785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com    }
6550785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com
6560785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com    if (type == gl::SAMPLER_PIXEL)
6570785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com    {
6580785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com        if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS)
6590785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com        {
6600785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com            ERR("Pixel shader sampler index %i is not valid.", index);
6610785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com            return;
6620785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com        }
6630785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com
66491382e555f35727043b6011e7f01fb2c74950fdbGeoff Lang        if (forceSetTexture || mCurPixelSRVs[index] != textureSRV)
665e33c8bfa0799f8dcd74a0ac88aacd4247f302386daniel@transgaming.com        {
666e33c8bfa0799f8dcd74a0ac88aacd4247f302386daniel@transgaming.com            mDeviceContext->PSSetShaderResources(index, 1, &textureSRV);
667e33c8bfa0799f8dcd74a0ac88aacd4247f302386daniel@transgaming.com        }
668e33c8bfa0799f8dcd74a0ac88aacd4247f302386daniel@transgaming.com
66991382e555f35727043b6011e7f01fb2c74950fdbGeoff Lang        mCurPixelSRVs[index] = textureSRV;
6700785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com    }
6710785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com    else if (type == gl::SAMPLER_VERTEX)
6720785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com    {
673233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com        if (index < 0 || index >= (int)getMaxVertexTextureImageUnits())
6740785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com        {
6750785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com            ERR("Vertex shader sampler index %i is not valid.", index);
6760785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com            return;
6770785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com        }
6780785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com
67991382e555f35727043b6011e7f01fb2c74950fdbGeoff Lang        if (forceSetTexture || mCurVertexSRVs[index] != textureSRV)
680e33c8bfa0799f8dcd74a0ac88aacd4247f302386daniel@transgaming.com        {
681e33c8bfa0799f8dcd74a0ac88aacd4247f302386daniel@transgaming.com            mDeviceContext->VSSetShaderResources(index, 1, &textureSRV);
682e33c8bfa0799f8dcd74a0ac88aacd4247f302386daniel@transgaming.com        }
683e33c8bfa0799f8dcd74a0ac88aacd4247f302386daniel@transgaming.com
68491382e555f35727043b6011e7f01fb2c74950fdbGeoff Lang        mCurVertexSRVs[index] = textureSRV;
6850785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com    }
6860785fad34cf919f9158f51b0e981bf345a748273daniel@transgaming.com    else UNREACHABLE();
6871d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
6881d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
6891bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.orgbool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[])
6901bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org{
6911bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org    for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++)
6921bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org    {
6931bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org        const gl::Buffer *uniformBuffer = vertexUniformBuffers[uniformBufferIndex];
6941bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org        if (uniformBuffer)
6951bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org        {
6961bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org            BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
6979c53f1e951d3fe883a7946161f3c53f25f49e369Geoff Lang            ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
6981bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org
6991bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org            if (!constantBuffer)
7001bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org            {
7011bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org                return false;
7021bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org            }
7031bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org
704c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang            if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial())
705c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang            {
706c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang                mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers() + uniformBufferIndex,
707c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang                                                     1, &constantBuffer);
708c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang                mCurrentConstantBufferVS[uniformBufferIndex] = bufferStorage->getSerial();
709c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang            }
7101bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org        }
7111bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org    }
7121bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org
7131bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org    for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++)
7141bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org    {
7151bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org        const gl::Buffer *uniformBuffer = fragmentUniformBuffers[uniformBufferIndex];
7161bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org        if (uniformBuffer)
7171bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org        {
7181bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org            BufferStorage11 *bufferStorage = BufferStorage11::makeBufferStorage11(uniformBuffer->getStorage());
7199c53f1e951d3fe883a7946161f3c53f25f49e369Geoff Lang            ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
7201bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org
7211bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org            if (!constantBuffer)
7221bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org            {
7231bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org                return false;
7241bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org            }
7251bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org
726c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang            if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial())
727c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang            {
728c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang                mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers() + uniformBufferIndex,
729c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang                                                     1, &constantBuffer);
730c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang                mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial();
731c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang            }
7321bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org        }
7331bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org    }
7341bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org
7351bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org    return true;
7361bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org}
7371bddfb984b4ce6f8422a877097e60aca956f5661shannonwoods@chromium.org
738237bc7e55bb631ebd1f5e7981b30b8a2eafbb606daniel@transgaming.comvoid Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
739493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com{
740237bc7e55bb631ebd1f5e7981b30b8a2eafbb606daniel@transgaming.com    if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
741dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com    {
742aea8e947d3f07df76086009293be59570354a174Nicolas Capens        ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled);
743dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com        if (!dxRasterState)
744dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com        {
7450f9b32095e50a386babf799d6a5e47704a00795adaniel@transgaming.com            ERR("NULL rasterizer state returned by RenderStateCache::getRasterizerState, setting the default"
746dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com                "rasterizer state.");
747dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com        }
748dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com
749dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com        mDeviceContext->RSSetState(dxRasterState);
750dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com
751dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com        mCurRasterState = rasterState;
752dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com    }
753dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com
754dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com    mForceSetRasterState = false;
755493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com}
756493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com
757c142e9da6a66c447bc0e519505fe9cf6adcc6ee6Geoff Langvoid Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
758493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com                               unsigned int sampleMask)
759493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com{
760f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com    if (mForceSetBlendState ||
761f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com        memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 ||
7622a64ee4479728d804e1ecd8d0d10e83f00cf4f29Geoff Lang        memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0 ||
763f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com        sampleMask != mCurSampleMask)
764f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com    {
765c142e9da6a66c447bc0e519505fe9cf6adcc6ee6Geoff Lang        ID3D11BlendState *dxBlendState = mStateCache.getBlendState(framebuffer, blendState);
766f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com        if (!dxBlendState)
767f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com        {
768f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com            ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default "
769f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com                "blend state.");
770f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com        }
771f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com
772568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org        float blendColors[4] = {0.0f};
773568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org        if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
774568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org            blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
775568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org        {
776568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org            blendColors[0] = blendColor.red;
777568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org            blendColors[1] = blendColor.green;
778568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org            blendColors[2] = blendColor.blue;
779568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org            blendColors[3] = blendColor.alpha;
780568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org        }
781568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org        else
782568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org        {
783568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org            blendColors[0] = blendColor.alpha;
784568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org            blendColors[1] = blendColor.alpha;
785568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org            blendColors[2] = blendColor.alpha;
786568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org            blendColors[3] = blendColor.alpha;
787568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org        }
788568c82e7367e620836f9f12c7e9009cb4301f1e7shannonwoods@chromium.org
789f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com        mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
790f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com
791f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com        mCurBlendState = blendState;
792f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com        mCurBlendColor = blendColor;
793f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com        mCurSampleMask = sampleMask;
794f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com    }
795f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com
796f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com    mForceSetBlendState = false;
797493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com}
798493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com
79908c331d42f31f8291238695d86db53d760e0b330daniel@transgaming.comvoid Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
8003a0ef48010e6a3e95c9d72f982ab6d3d4cad0c6fdaniel@transgaming.com                                      int stencilBackRef, bool frontFaceCCW)
801493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com{
8025503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com    if (mForceSetDepthStencilState ||
8035503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com        memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
8045503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com        stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
8055503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com    {
8065503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com        if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
8075503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com            stencilRef != stencilBackRef ||
8085503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com            depthStencilState.stencilMask != depthStencilState.stencilBackMask)
8095503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com        {
8105503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com            ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are "
8115503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com                "invalid under WebGL.");
812779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com            return gl::error(GL_INVALID_OPERATION);
8135503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com        }
8145503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com
8155503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com        ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState);
8165503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com        if (!dxDepthStencilState)
8175503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com        {
8185503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com            ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, "
8195503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com                "setting the default depth stencil state.");
8205503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com        }
8215503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com
822ec91cd3246b612001ce3f06d4ba7e242ba4f66e1Jamie Madill        // Max D3D11 stencil reference value is 0xFF, corresponding to the max 8 bits in a stencil buffer
823ec91cd3246b612001ce3f06d4ba7e242ba4f66e1Jamie Madill        // GL specifies we should clamp the ref value to the nearest bit depth when doing stencil ops
824ec91cd3246b612001ce3f06d4ba7e242ba4f66e1Jamie Madill        META_ASSERT(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF);
825ec91cd3246b612001ce3f06d4ba7e242ba4f66e1Jamie Madill        META_ASSERT(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF);
8260bf3a982d7ef58fe1fca86c4aaf19cb6e5c86743Geoff Lang        UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu);
827ec91cd3246b612001ce3f06d4ba7e242ba4f66e1Jamie Madill
8280bf3a982d7ef58fe1fca86c4aaf19cb6e5c86743Geoff Lang        mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
8295503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com
8305503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com        mCurDepthStencilState = depthStencilState;
8315503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com        mCurStencilRef = stencilRef;
8325503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com        mCurStencilBackRef = stencilBackRef;
8335503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com    }
8345503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com
8355503fd031e3e5491d998a643218b1aa6a8c022c9daniel@transgaming.com    mForceSetDepthStencilState = false;
836493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com}
837493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com
838d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.comvoid Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
839493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com{
840d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com    if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
841d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com        enabled != mScissorEnabled)
842dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com    {
843d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com        if (enabled)
844d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com        {
845d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com            D3D11_RECT rect;
8468ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com            rect.left = std::max(0, scissor.x);
8478ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com            rect.top = std::max(0, scissor.y);
8488ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com            rect.right = scissor.x + std::max(0, scissor.width);
8498ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com            rect.bottom = scissor.y + std::max(0, scissor.height);
850d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com
851d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com            mDeviceContext->RSSetScissorRects(1, &rect);
852d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com        }
853dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com
854d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com        if (enabled != mScissorEnabled)
855d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com        {
856d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com            mForceSetRasterState = true;
857d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com        }
858dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com
859dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com        mCurScissor = scissor;
860d55e8c1b48f16f93cb89798fc3640047eb74d3fddaniel@transgaming.com        mScissorEnabled = enabled;
861dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com    }
862dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com
863dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com    mForceSetScissor = false;
864493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com}
865493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com
8661298518804934fac7f8ecd37ad58a5ac100cff36daniel@transgaming.combool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
8670b236e2ec3c32b79d1abca881a32cbf53027e3d3shannon.woods@transgaming.com                             bool ignoreViewport)
86883e80ee442d5f793b89aaef7d1b5db3cde2f4b4ddaniel@transgaming.com{
8694c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com    gl::Rectangle actualViewport = viewport;
8704c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com    float actualZNear = gl::clamp01(zNear);
8714c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com    float actualZFar = gl::clamp01(zFar);
8724c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com    if (ignoreViewport)
8734c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com    {
8744c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com        actualViewport.x = 0;
8754c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com        actualViewport.y = 0;
8764c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com        actualViewport.width = mRenderTargetDesc.width;
8774c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com        actualViewport.height = mRenderTargetDesc.height;
8784c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com        actualZNear = 0.0f;
8794c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com        actualZFar = 1.0f;
8804c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com    }
8815367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com
8828ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    // Get D3D viewport bounds, which depends on the feature level
8838ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    const Range& viewportBounds = getViewportBounds();
8848ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com
8858ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    // Clamp width and height first to the gl maximum, then clamp further if we extend past the D3D maximum bounds
8865367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com    D3D11_VIEWPORT dxViewport;
8878ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    dxViewport.TopLeftX = gl::clamp(actualViewport.x, viewportBounds.start, viewportBounds.end);
8888ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    dxViewport.TopLeftY = gl::clamp(actualViewport.y, viewportBounds.start, viewportBounds.end);
8898ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    dxViewport.Width = gl::clamp(actualViewport.width, 0, getMaxViewportDimension());
8908ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    dxViewport.Height = gl::clamp(actualViewport.height, 0, getMaxViewportDimension());
8918ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    dxViewport.Width = std::min((int)dxViewport.Width, viewportBounds.end - static_cast<int>(dxViewport.TopLeftX));
8928ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    dxViewport.Height = std::min((int)dxViewport.Height, viewportBounds.end - static_cast<int>(dxViewport.TopLeftY));
8934c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com    dxViewport.MinDepth = actualZNear;
8944c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com    dxViewport.MaxDepth = actualZFar;
8955367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com
8965367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com    if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
8975367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com    {
8985367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com        return false;   // Nothing to render
8995367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com    }
9005367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com
901ed36abd83e40bb1c0f4af9ea7314906b86ea3cdddaniel@transgaming.com    bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
902ed36abd83e40bb1c0f4af9ea7314906b86ea3cdddaniel@transgaming.com                           actualZNear != mCurNear || actualZFar != mCurFar;
9034c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com
9045367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com    if (viewportChanged)
9055367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com    {
9065367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com        mDeviceContext->RSSetViewports(1, &dxViewport);
9075367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com
9084c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com        mCurViewport = actualViewport;
9094c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com        mCurNear = actualZNear;
9104c4ce233dc7953a07c126e0cba1b43c2a89ecc80daniel@transgaming.com        mCurFar = actualZFar;
9115367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com
912a14ecf36b52fb0399deee3fab6f0c8d8c0abba5eshannon.woods@transgaming.com        mPixelConstants.viewCoords[0] = actualViewport.width  * 0.5f;
913a14ecf36b52fb0399deee3fab6f0c8d8c0abba5eshannon.woods@transgaming.com        mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f;
914a14ecf36b52fb0399deee3fab6f0c8d8c0abba5eshannon.woods@transgaming.com        mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width  * 0.5f);
915a14ecf36b52fb0399deee3fab6f0c8d8c0abba5eshannon.woods@transgaming.com        mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
916ed36abd83e40bb1c0f4af9ea7314906b86ea3cdddaniel@transgaming.com
9175fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
9185fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
919ed36abd83e40bb1c0f4af9ea7314906b86ea3cdddaniel@transgaming.com
9205fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        mVertexConstants.depthRange[0] = actualZNear;
9215fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        mVertexConstants.depthRange[1] = actualZFar;
9225fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        mVertexConstants.depthRange[2] = actualZFar - actualZNear;
923ed36abd83e40bb1c0f4af9ea7314906b86ea3cdddaniel@transgaming.com
9245fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        mPixelConstants.depthRange[0] = actualZNear;
9255fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        mPixelConstants.depthRange[1] = actualZFar;
9265fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        mPixelConstants.depthRange[2] = actualZFar - actualZNear;
9275367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com    }
9285367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com
9295367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com    mForceSetViewport = false;
93083e80ee442d5f793b89aaef7d1b5db3cde2f4b4ddaniel@transgaming.com    return true;
93183e80ee442d5f793b89aaef7d1b5db3cde2f4b4ddaniel@transgaming.com}
93283e80ee442d5f793b89aaef7d1b5db3cde2f4b4ddaniel@transgaming.com
93391207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.combool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
93491207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com{
935c52be63dba2e6297fc480124330f8f24e706c998daniel@transgaming.com    D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
9360b03b06c0e53c6d33e243aa9c2a2f5e89e146269daniel@transgaming.com
93757e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang    GLsizei minCount = 0;
93857e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang
9390b03b06c0e53c6d33e243aa9c2a2f5e89e146269daniel@transgaming.com    switch (mode)
9400b03b06c0e53c6d33e243aa9c2a2f5e89e146269daniel@transgaming.com    {
94157e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang      case GL_POINTS:         primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;   minCount = 1; break;
94257e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang      case GL_LINES:          primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;      minCount = 2; break;
94357e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang      case GL_LINE_LOOP:      primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;     minCount = 2; break;
94457e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang      case GL_LINE_STRIP:     primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;     minCount = 2; break;
94557e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang      case GL_TRIANGLES:      primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;  minCount = 3; break;
94657e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang      case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; minCount = 3; break;
9474fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com          // emulate fans via rewriting index buffer
94857e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang      case GL_TRIANGLE_FAN:   primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;  minCount = 3; break;
9490b03b06c0e53c6d33e243aa9c2a2f5e89e146269daniel@transgaming.com      default:
950779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_INVALID_ENUM, false);
9510b03b06c0e53c6d33e243aa9c2a2f5e89e146269daniel@transgaming.com    }
9520b03b06c0e53c6d33e243aa9c2a2f5e89e146269daniel@transgaming.com
9534c09586e7c8ebff631e4c459fc5701a0c95e9693Geoff Lang    if (primitiveTopology != mCurrentPrimitiveTopology)
9544c09586e7c8ebff631e4c459fc5701a0c95e9693Geoff Lang    {
9554c09586e7c8ebff631e4c459fc5701a0c95e9693Geoff Lang        mDeviceContext->IASetPrimitiveTopology(primitiveTopology);
9564c09586e7c8ebff631e4c459fc5701a0c95e9693Geoff Lang        mCurrentPrimitiveTopology = primitiveTopology;
9574c09586e7c8ebff631e4c459fc5701a0c95e9693Geoff Lang    }
95891207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com
95957e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang    return count >= minCount;
96091207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com}
96191207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com
96291207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.combool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
963493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com{
96480fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    // Get the color render buffer and serial
965f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com    // Also extract the render target dimensions and view
966f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com    unsigned int renderTargetWidth = 0;
967f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com    unsigned int renderTargetHeight = 0;
968f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com    GLenum renderTargetFormat = 0;
969f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com    unsigned int renderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {0};
970f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com    ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
971f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com    bool missingColorRenderTarget = true;
97280fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com
973f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com    for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
974f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com    {
9754059a3894ef3a5419a1bdc091a17eab552cd9c67shannon.woods%transgaming.com@gtempaccount.com        const GLenum drawBufferState = framebuffer->getDrawBufferState(colorAttachment);
9764059a3894ef3a5419a1bdc091a17eab552cd9c67shannon.woods%transgaming.com@gtempaccount.com
9774059a3894ef3a5419a1bdc091a17eab552cd9c67shannon.woods%transgaming.com@gtempaccount.com        if (framebuffer->getColorbufferType(colorAttachment) != GL_NONE && drawBufferState != GL_NONE)
97880fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        {
9794059a3894ef3a5419a1bdc091a17eab552cd9c67shannon.woods%transgaming.com@gtempaccount.com            // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order)
9804059a3894ef3a5419a1bdc091a17eab552cd9c67shannon.woods%transgaming.com@gtempaccount.com            ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
9814059a3894ef3a5419a1bdc091a17eab552cd9c67shannon.woods%transgaming.com@gtempaccount.com
9823c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill            gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(colorAttachment);
98380fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com
984f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            if (!colorbuffer)
985f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            {
986f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com                ERR("render target pointer unexpectedly null.");
987f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com                return false;
988f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            }
989f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com
990f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            // check for zero-sized default framebuffer, which is a special case.
991f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            // in this case we do not wish to modify any state and just silently return false.
992f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            // this will not report any gl error but will cause the calling method to return.
993f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
994f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            {
995f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com                return false;
996f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            }
997f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com
998f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            renderTargetSerials[colorAttachment] = colorbuffer->getSerial();
999f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com
1000f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            // Extract the render target dimensions and view
1001f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
1002f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            if (!renderTarget)
1003f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            {
1004f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com                ERR("render target pointer unexpectedly null.");
1005f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com                return false;
1006f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            }
1007f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com
1008f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
1009f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            if (!framebufferRTVs[colorAttachment])
1010f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            {
1011f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com                ERR("render target view pointer unexpectedly null.");
1012f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com                return false;
1013f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            }
10143e3da5833393098b525d24a03ef105e75666f13fshannon.woods@transgaming.com
1015f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            if (missingColorRenderTarget)
1016f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            {
1017f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com                renderTargetWidth = colorbuffer->getWidth();
1018f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com                renderTargetHeight = colorbuffer->getHeight();
1019f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com                renderTargetFormat = colorbuffer->getActualFormat();
1020f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com                missingColorRenderTarget = false;
1021f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            }
1022ba597af987a0b6a8357077d9d770cdffb6c4540eJamie Madill
102391382e555f35727043b6011e7f01fb2c74950fdbGeoff Lang            // TODO: Detect if this color buffer is already bound as a texture and unbind it first to prevent
102491382e555f35727043b6011e7f01fb2c74950fdbGeoff Lang            //       D3D11 warnings.
1025f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com        }
102680fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    }
1027dcf1e676adecaa793953f46739f24e7ef4efba8bdaniel@transgaming.com
102880fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    // Get the depth stencil render buffer and serials
10293c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    gl::FramebufferAttachment *depthStencil = NULL;
103080fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    unsigned int depthbufferSerial = 0;
103180fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    unsigned int stencilbufferSerial = 0;
103280fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    if (framebuffer->getDepthbufferType() != GL_NONE)
103380fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    {
103480fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        depthStencil = framebuffer->getDepthbuffer();
103580fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        if (!depthStencil)
103680fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        {
103780fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com            ERR("Depth stencil pointer unexpectedly null.");
1038f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            SafeRelease(framebufferRTVs);
103980fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com            return false;
104080fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        }
104180fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com
104280fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        depthbufferSerial = depthStencil->getSerial();
104380fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    }
104480fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    else if (framebuffer->getStencilbufferType() != GL_NONE)
104580fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    {
104680fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        depthStencil = framebuffer->getStencilbuffer();
104780fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        if (!depthStencil)
104880fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        {
104980fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com            ERR("Depth stencil pointer unexpectedly null.");
1050f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            SafeRelease(framebufferRTVs);
105180fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com            return false;
105280fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        }
105380fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com
105480fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        stencilbufferSerial = depthStencil->getSerial();
105580fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    }
105680fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com
105780fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    ID3D11DepthStencilView* framebufferDSV = NULL;
105880fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    if (depthStencil)
105980fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    {
106080fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil());
106180fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        if (!depthStencilRenderTarget)
106280fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        {
106380fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com            ERR("render target pointer unexpectedly null.");
1064f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            SafeRelease(framebufferRTVs);
106580fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com            return false;
106680fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        }
106780fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com
106880fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
106980fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        if (!framebufferDSV)
107080fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        {
107180fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com            ERR("depth stencil view pointer unexpectedly null.");
1072f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            SafeRelease(framebufferRTVs);
107380fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com            return false;
107480fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        }
107580fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com
107680fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        // If there is no render buffer, the width, height and format values come from
107780fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        // the depth stencil
1078f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com        if (missingColorRenderTarget)
107980fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        {
108080fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com            renderTargetWidth = depthStencil->getWidth();
108180fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com            renderTargetHeight = depthStencil->getHeight();
108280fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com            renderTargetFormat = depthStencil->getActualFormat();
108380fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        }
108480fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    }
108580fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com
108680fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    // Apply the render target and depth stencil
108780fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
1088f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com        memcmp(renderTargetSerials, mAppliedRenderTargetSerials, sizeof(renderTargetSerials)) != 0 ||
108980fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        depthbufferSerial != mAppliedDepthbufferSerial ||
109080fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        stencilbufferSerial != mAppliedStencilbufferSerial)
109180fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    {
1092f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com        mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), framebufferRTVs, framebufferDSV);
109380fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com
109480fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        mRenderTargetDesc.width = renderTargetWidth;
109580fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        mRenderTargetDesc.height = renderTargetHeight;
109680fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        mRenderTargetDesc.format = renderTargetFormat;
10978ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com        mForceSetViewport = true;
10988ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com        mForceSetScissor = true;
1099c142e9da6a66c447bc0e519505fe9cf6adcc6ee6Geoff Lang        mForceSetBlendState = true;
110080fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com
1101aea8e947d3f07df76086009293be59570354a174Nicolas Capens        if (!mDepthStencilInitialized)
110280fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        {
110380fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com            mForceSetRasterState = true;
110480fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        }
110580fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com
1106f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com        for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
1107f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com        {
1108f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com            mAppliedRenderTargetSerials[rtIndex] = renderTargetSerials[rtIndex];
1109f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com        }
111080fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        mAppliedDepthbufferSerial = depthbufferSerial;
111180fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        mAppliedStencilbufferSerial = stencilbufferSerial;
111280fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        mRenderTargetDescInitialized = true;
111380fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com        mDepthStencilInitialized = true;
111480fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com    }
111580fc3326493eee780094e1f28e60d6e8c27fbdfddaniel@transgaming.com
111642477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    invalidateFramebufferSwizzles(framebuffer);
111742477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
1118ae39ee280d5e15b8064402b75e8daecbe4146b98daniel@transgaming.com    return true;
1119493d4f872b528410dee998b38c89a31492a23895daniel@transgaming.com}
11201d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
112157a8972e5ddf7611860d9767c8aed4793c3929afJamie MadillGLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
1122a857c36bc1e9f1178c5eaa3e80bfe543a5408467Jamie Madill                                     GLint first, GLsizei count, GLsizei instances)
1123def9f0f35beb8606b73bab418c69f1047252e50edaniel@transgaming.com{
1124c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
1125a857c36bc1e9f1178c5eaa3e80bfe543a5408467Jamie Madill    GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
1126c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    if (err != GL_NO_ERROR)
1127c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    {
1128c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com        return err;
1129c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    }
1130da495a111d6837e456b42a7a270af022f7f50e14daniel@transgaming.com
1131c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    return mInputLayoutCache.applyVertexBuffers(attributes, programBinary);
1132def9f0f35beb8606b73bab418c69f1047252e50edaniel@transgaming.com}
1133def9f0f35beb8606b73bab418c69f1047252e50edaniel@transgaming.com
1134312404870905e1eff46e21632c1c2f2143af4694daniel@transgaming.comGLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
113591207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com{
1136c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
1137c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com
1138c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    if (err == GL_NO_ERROR)
1139c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    {
11407840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang        ID3D11Buffer *buffer = NULL;
114175551cf9a7c65bcdb9f9fe44ac78ca15da37942eNicolas Capens        DXGI_FORMAT bufferFormat = (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
1142a1229a3a67bcbe9be1381b787be3669c07548c3fshannon.woods@transgaming.com
11437840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang        if (indexInfo->storage)
11447840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang        {
11457840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang            BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo->storage);
11467840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang            buffer = storage->getBuffer(BUFFER_USAGE_INDEX);
1147a1229a3a67bcbe9be1381b787be3669c07548c3fshannon.woods@transgaming.com        }
11487840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang        else
1149c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com        {
115075551cf9a7c65bcdb9f9fe44ac78ca15da37942eNicolas Capens            IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer);
11517840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang            buffer = indexBuffer->getBuffer();
11527840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang        }
1153c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com
11547840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang        if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset)
11557840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang        {
11567840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang            mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset);
1157a1229a3a67bcbe9be1381b787be3669c07548c3fshannon.woods@transgaming.com
11587840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang            mAppliedIB = buffer;
11597840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang            mAppliedIBFormat = bufferFormat;
11607fbf486e4bf16530f84a88fa139641d82b334254daniel@transgaming.com            mAppliedIBOffset = indexInfo->startOffset;
1161c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com        }
1162c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    }
116391207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com
1164c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    return err;
116591207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com}
116691207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com
1167eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Langvoid Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[])
1168eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang{
1169eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang    ID3D11Buffer* d3dBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
1170eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang    UINT d3dOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
1171eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang    bool requiresUpdate = false;
1172eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang    for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
1173eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang    {
1174eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        if (transformFeedbackBuffers[i])
1175eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        {
1176eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang            BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(transformFeedbackBuffers[i]->getStorage());
1177eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang            ID3D11Buffer *buffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
1178eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang
1179eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang            d3dBuffers[i] = buffer;
1180eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang            d3dOffsets[i] = (mAppliedTFBuffers[i] != buffer) ? static_cast<UINT>(offsets[i]) : -1;
1181eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        }
1182eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        else
1183eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        {
1184eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang            d3dBuffers[i] = NULL;
1185eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang            d3dOffsets[i] = 0;
1186eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        }
1187eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang
1188eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        if (d3dBuffers[i] != mAppliedTFBuffers[i] || offsets[i] != mAppliedTFOffsets[i])
1189eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        {
1190eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang            requiresUpdate = true;
1191eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        }
1192eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang    }
1193eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang
1194eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang    if (requiresUpdate)
1195eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang    {
1196eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        mDeviceContext->SOSetTargets(ArraySize(d3dBuffers), d3dBuffers, d3dOffsets);
1197eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
1198eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        {
1199eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang            mAppliedTFBuffers[i] = d3dBuffers[i];
1200eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang            mAppliedTFOffsets[i] = offsets[i];
1201eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        }
1202eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang    }
1203eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang}
1204eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang
12054c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Langvoid Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive)
120691207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com{
12074c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    if (mode == GL_POINTS && transformFeedbackActive)
12084c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    {
12094c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        // Since point sprites are generated with a geometry shader, too many vertices will
12104c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        // be written if transform feedback is active.  To work around this, draw only the points
12114c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        // with the stream out shader and no pixel shader to feed the stream out buffers and then
12124c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        // draw again with the point sprite geometry shader to rasterize the point sprites.
12134c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang
12144c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        mDeviceContext->PSSetShader(NULL, NULL, 0);
12154c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang
12164c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        if (instances > 0)
12174c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        {
12184c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang            mDeviceContext->DrawInstanced(count, instances, 0, 0);
12194c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        }
12204c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        else
12214c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        {
12224c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang            mDeviceContext->Draw(count, 0);
12234c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        }
12244c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang
12254c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        mDeviceContext->GSSetShader(mCurPointGeometryShader, NULL, 0);
12264c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        mDeviceContext->PSSetShader(mAppliedPixelShader, NULL, 0);
12274c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang
12284c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        if (instances > 0)
12294c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        {
12304c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang            mDeviceContext->DrawInstanced(count, instances, 0, 0);
12314c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        }
12324c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        else
12334c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        {
12344c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang            mDeviceContext->Draw(count, 0);
12354c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        }
12364c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang
12374c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        mDeviceContext->GSSetShader(mAppliedGeometryShader, NULL, 0);
12384c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    }
12394c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    else if (mode == GL_LINE_LOOP)
12401ef096726782644f8fae5529ee90a7aa19ab018ddaniel@transgaming.com    {
12411ef096726782644f8fae5529ee90a7aa19ab018ddaniel@transgaming.com        drawLineLoop(count, GL_NONE, NULL, 0, NULL);
12421ef096726782644f8fae5529ee90a7aa19ab018ddaniel@transgaming.com    }
12434fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    else if (mode == GL_TRIANGLE_FAN)
12444fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    {
124500032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com        drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances);
12464fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    }
12471ef096726782644f8fae5529ee90a7aa19ab018ddaniel@transgaming.com    else if (instances > 0)
12481ef096726782644f8fae5529ee90a7aa19ab018ddaniel@transgaming.com    {
124900032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com        mDeviceContext->DrawInstanced(count, instances, 0, 0);
12501ef096726782644f8fae5529ee90a7aa19ab018ddaniel@transgaming.com    }
12511ef096726782644f8fae5529ee90a7aa19ab018ddaniel@transgaming.com    else
12521ef096726782644f8fae5529ee90a7aa19ab018ddaniel@transgaming.com    {
12531ef096726782644f8fae5529ee90a7aa19ab018ddaniel@transgaming.com        mDeviceContext->Draw(count, 0);
12541ef096726782644f8fae5529ee90a7aa19ab018ddaniel@transgaming.com    }
125591207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com}
125691207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com
12574c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Langvoid Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
12584c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang                              gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances)
125991207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com{
1260c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    if (mode == GL_LINE_LOOP)
1261c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    {
1262c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
1263c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    }
12644fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    else if (mode == GL_TRIANGLE_FAN)
12654fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    {
126600032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com        drawTriangleFan(count, type, indices, indexInfo.minIndex, elementArrayBuffer, instances);
126700032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com    }
126800032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com    else if (instances > 0)
126900032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com    {
127000032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com        mDeviceContext->DrawIndexedInstanced(count, instances, 0, -static_cast<int>(indexInfo.minIndex), 0);
12714fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    }
1272c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    else
1273c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    {
12749f7ede6780e8fc8e73387707843989aa16deb0c6daniel@transgaming.com        mDeviceContext->DrawIndexed(count, 0, -static_cast<int>(indexInfo.minIndex));
1275c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    }
1276c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com}
1277c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com
1278c51143010f903323679266df2aa47a233c964f12daniel@transgaming.comvoid Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
1279c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com{
1280c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    // Get the raw indices for an indexed draw
1281c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    if (type != GL_NONE && elementArrayBuffer)
1282c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    {
1283c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        gl::Buffer *indexBuffer = elementArrayBuffer;
1284766554167a9581c059a81dcbce05f6355220c063shannon.woods@transgaming.com        BufferStorage *storage = indexBuffer->getStorage();
1285c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        intptr_t offset = reinterpret_cast<intptr_t>(indices);
1286766554167a9581c059a81dcbce05f6355220c063shannon.woods@transgaming.com        indices = static_cast<const GLubyte*>(storage->getData()) + offset;
1287c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    }
1288c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com
1289c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    if (!mLineLoopIB)
1290c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    {
1291c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        mLineLoopIB = new StreamingIndexBufferInterface(this);
1292c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
1293c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        {
1294c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com            delete mLineLoopIB;
1295c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com            mLineLoopIB = NULL;
1296c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com
1297c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com            ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP.");
1298779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com            return gl::error(GL_OUT_OF_MEMORY);
1299c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        }
1300c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    }
1301c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com
130257e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang    // Checked by Renderer11::applyPrimitiveType
130357e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang    ASSERT(count >= 0);
130457e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang
130557e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang    if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int)))
1306eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang    {
1307eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang        ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required.");
1308eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang        return gl::error(GL_OUT_OF_MEMORY);
1309eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang    }
1310eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang
131157e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang    const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int);
1312c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
1313c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    {
1314c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
1315779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY);
1316c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    }
1317c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com
1318c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    void* mappedMemory = NULL;
1319a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang    unsigned int offset;
1320a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang    if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset))
1321c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    {
1322c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        ERR("Could not map index buffer for GL_LINE_LOOP.");
1323779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY);
1324c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    }
1325c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com
1326c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
1327a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang    unsigned int indexBufferOffset = offset;
1328c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com
1329c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    switch (type)
1330c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    {
1331c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com      case GL_NONE:   // Non-indexed draw
1332c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        for (int i = 0; i < count; i++)
1333c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        {
1334c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com            data[i] = i;
1335c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        }
1336c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        data[count] = 0;
1337c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        break;
1338c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com      case GL_UNSIGNED_BYTE:
1339c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        for (int i = 0; i < count; i++)
1340c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        {
1341c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com            data[i] = static_cast<const GLubyte*>(indices)[i];
1342c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        }
1343c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        data[count] = static_cast<const GLubyte*>(indices)[0];
1344c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        break;
1345c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com      case GL_UNSIGNED_SHORT:
1346c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        for (int i = 0; i < count; i++)
1347c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        {
1348c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com            data[i] = static_cast<const GLushort*>(indices)[i];
1349c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        }
1350c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        data[count] = static_cast<const GLushort*>(indices)[0];
1351c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        break;
1352c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com      case GL_UNSIGNED_INT:
1353c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        for (int i = 0; i < count; i++)
1354c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        {
1355c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com            data[i] = static_cast<const GLuint*>(indices)[i];
1356c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        }
1357c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        data[count] = static_cast<const GLuint*>(indices)[0];
1358c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        break;
1359c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com      default: UNREACHABLE();
1360c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    }
1361c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com
1362c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    if (!mLineLoopIB->unmapBuffer())
1363c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    {
1364c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com        ERR("Could not unmap index buffer for GL_LINE_LOOP.");
1365779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY);
1366c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    }
1367c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com
13687840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang    IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer());
13697840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang    ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer();
13707840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang    DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat();
1371c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com
13727840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang    if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset)
13737840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang    {
137475551cf9a7c65bcdb9f9fe44ac78ca15da37942eNicolas Capens        mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset);
13757840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang        mAppliedIB = d3dIndexBuffer;
13767840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang        mAppliedIBFormat = indexFormat;
13777fbf486e4bf16530f84a88fa139641d82b334254daniel@transgaming.com        mAppliedIBOffset = indexBufferOffset;
1378c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com    }
1379c51143010f903323679266df2aa47a233c964f12daniel@transgaming.com
13801ef096726782644f8fae5529ee90a7aa19ab018ddaniel@transgaming.com    mDeviceContext->DrawIndexed(count + 1, 0, -minIndex);
138191207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com}
138291207b79c85830aff4420dea395fb12ff20c3f4edaniel@transgaming.com
138300032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.comvoid Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances)
13844fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com{
13854fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    // Get the raw indices for an indexed draw
13864fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    if (type != GL_NONE && elementArrayBuffer)
13874fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    {
13884fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        gl::Buffer *indexBuffer = elementArrayBuffer;
1389766554167a9581c059a81dcbce05f6355220c063shannon.woods@transgaming.com        BufferStorage *storage = indexBuffer->getStorage();
13904fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        intptr_t offset = reinterpret_cast<intptr_t>(indices);
1391766554167a9581c059a81dcbce05f6355220c063shannon.woods@transgaming.com        indices = static_cast<const GLubyte*>(storage->getData()) + offset;
13924fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    }
13934fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com
13944fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    if (!mTriangleFanIB)
13954fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    {
13964fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        mTriangleFanIB = new StreamingIndexBufferInterface(this);
13974fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
13984fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        {
13994fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            delete mTriangleFanIB;
14004fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            mTriangleFanIB = NULL;
14014fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com
14024fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN.");
1403779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com            return gl::error(GL_OUT_OF_MEMORY);
14044fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        }
14054fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    }
14064fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com
140757e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang    // Checked by Renderer11::applyPrimitiveType
140857e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang    ASSERT(count >= 3);
140957e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang
1410eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang    const unsigned int numTris = count - 2;
1411eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang
141257e713e87cca4657eba98d31951d5ae60c9c1de4Geoff Lang    if (numTris > (std::numeric_limits<unsigned int>::max() / (sizeof(unsigned int) * 3)))
1413eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang    {
1414eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang        ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required.");
1415eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang        return gl::error(GL_OUT_OF_MEMORY);
1416eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang    }
1417eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang
1418eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang    const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
14194fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
14204fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    {
14214fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN.");
1422779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY);
14234fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    }
14244fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com
14254fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    void* mappedMemory = NULL;
1426a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang    unsigned int offset;
1427a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang    if (!mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset))
14284fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    {
14294fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        ERR("Could not map scratch index buffer for GL_TRIANGLE_FAN.");
1430779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY);
14314fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    }
14324fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com
14334fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
1434a36ead4a7d5641181ab994a13b7d5027c1b5bd07Geoff Lang    unsigned int indexBufferOffset = offset;
14354fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com
14364fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    switch (type)
14374fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    {
14384fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com      case GL_NONE:   // Non-indexed draw
1439eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang        for (unsigned int i = 0; i < numTris; i++)
14404fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        {
14414fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            data[i*3 + 0] = 0;
14424fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            data[i*3 + 1] = i + 1;
14434fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            data[i*3 + 2] = i + 2;
14444fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        }
14454fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        break;
14464fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com      case GL_UNSIGNED_BYTE:
1447eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang        for (unsigned int i = 0; i < numTris; i++)
14484fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        {
14494fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
14504fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
14514fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
14524fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        }
14534fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        break;
14544fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com      case GL_UNSIGNED_SHORT:
1455eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang        for (unsigned int i = 0; i < numTris; i++)
14564fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        {
14574fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
14584fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
14594fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
14604fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        }
14614fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        break;
14624fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com      case GL_UNSIGNED_INT:
1463eadfd57b53d4762db884b57b0f6c453d2976c456Geoff Lang        for (unsigned int i = 0; i < numTris; i++)
14644fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        {
14654fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
14664fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
14674fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com            data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
14684fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        }
14694fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        break;
14704fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com      default: UNREACHABLE();
14714fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    }
14724fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com
14734fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    if (!mTriangleFanIB->unmapBuffer())
14744fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    {
14754fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        ERR("Could not unmap scratch index buffer for GL_TRIANGLE_FAN.");
1476779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY);
14774fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    }
14784fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com
14797840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang    IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer());
14807840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang    ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer();
14817840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang    DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat();
14824fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com
14837840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang    if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset)
14847840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang    {
148575551cf9a7c65bcdb9f9fe44ac78ca15da37942eNicolas Capens        mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset);
14867840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang        mAppliedIB = d3dIndexBuffer;
14877840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang        mAppliedIBFormat = indexFormat;
14884fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com        mAppliedIBOffset = indexBufferOffset;
14894fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com    }
14904fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com
149100032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com    if (instances > 0)
149200032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com    {
149300032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com        mDeviceContext->DrawIndexedInstanced(numTris * 3, instances, 0, -minIndex, 0);
149400032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com    }
149500032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com    else
149600032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com    {
149700032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com        mDeviceContext->DrawIndexed(numTris * 3, 0, -minIndex);
149800032cb2c77dfe812dda092ecfd938e66dce7f3cshannon.woods@transgaming.com    }
14994fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com}
15004fd1f989feaadab717e505c54dee64eff756c5abdaniel@transgaming.com
15014c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Langvoid Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[])
15025fbf177ce23fc52625e1d7a6914fd7a9ce12c311daniel@transgaming.com{
1503c5a8300026be5bd38ca022211ce7e078e92b9377Jamie Madill    ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
15046246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
15056246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
150643ccf3f88ef54beecbd8a8a7735790311621016cshannon.woods@transgaming.com
15076246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL);
1508e499141632259ca0189c07c5eb947b728ff4ebbedaniel@transgaming.com
15094c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    ID3D11PixelShader *pixelShader = NULL;
15104c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    // Skip pixel shader if we're doing rasterizer discard.
15114c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    if (!rasterizerDiscard)
15126246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    {
15134c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        pixelShader = (pixelExe ? ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader() : NULL);
15146246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    }
1515d4b2db254ed6cb0b3a60a4b0077a0c9aa11b7421daniel@transgaming.com
15164c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    ID3D11GeometryShader *geometryShader = NULL;
15174c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    if (transformFeedbackActive)
15184c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    {
15194c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        geometryShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getStreamOutShader() : NULL);
15204c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    }
15214c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    else if (mCurRasterState.pointDrawMode)
15220550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang    {
15234c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        geometryShader = (geometryExe ? ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader() : NULL);
15240550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang    }
15250550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang
15266246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    bool dirtyUniforms = false;
1527d4b2db254ed6cb0b3a60a4b0077a0c9aa11b7421daniel@transgaming.com
15286246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    if (vertexShader != mAppliedVertexShader)
15296246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    {
1530e499141632259ca0189c07c5eb947b728ff4ebbedaniel@transgaming.com        mDeviceContext->VSSetShader(vertexShader, NULL, 0);
15316246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill        mAppliedVertexShader = vertexShader;
15326246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill        dirtyUniforms = true;
1533dd2524c46ed4689c27adf3f9959435fd2906b621shannon.woods@transgaming.com    }
1534dd2524c46ed4689c27adf3f9959435fd2906b621shannon.woods@transgaming.com
15356246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    if (geometryShader != mAppliedGeometryShader)
15366246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    {
15376246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill        mDeviceContext->GSSetShader(geometryShader, NULL, 0);
15386246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill        mAppliedGeometryShader = geometryShader;
15396246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill        dirtyUniforms = true;
15406246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    }
1541dd2524c46ed4689c27adf3f9959435fd2906b621shannon.woods@transgaming.com
15424c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    if (geometryExe && mCurRasterState.pointDrawMode)
15434c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    {
15444c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        mCurPointGeometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader();
15454c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    }
15464c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    else
15474c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    {
15484c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang        mCurPointGeometryShader = NULL;
15494c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    }
15504c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang
15516246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    if (pixelShader != mAppliedPixelShader)
1552dd2524c46ed4689c27adf3f9959435fd2906b621shannon.woods@transgaming.com    {
15536246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill        mDeviceContext->PSSetShader(pixelShader, NULL, 0);
15546246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill        mAppliedPixelShader = pixelShader;
15556246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill        dirtyUniforms = true;
15566246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    }
15573e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com
15586246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    if (dirtyUniforms)
15596246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    {
15606246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill        programBinary->dirtyAllUniforms();
1561e499141632259ca0189c07c5eb947b728ff4ebbedaniel@transgaming.com    }
15625fbf177ce23fc52625e1d7a6914fd7a9ce12c311daniel@transgaming.com}
15635fbf177ce23fc52625e1d7a6914fd7a9ce12c311daniel@transgaming.com
15648ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madillvoid Renderer11::applyUniforms(const gl::ProgramBinary &programBinary)
1565ab1c14629ce8af6bc76b29452e2677a8f0cdfc1adaniel@transgaming.com{
1566834e8b7715c25e299c07c9d63f5be0a0ee6c5856Jamie Madill    const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms();
15675929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com
15685929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com    unsigned int totalRegisterCountVS = 0;
15695929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com    unsigned int totalRegisterCountPS = 0;
15705929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com
157121ba6478bb28924a634074f53d02c7b20f6dc1d5shannon.woods@transgaming.com    bool vertexUniformsDirty = false;
157221ba6478bb28924a634074f53d02c7b20f6dc1d5shannon.woods@transgaming.com    bool pixelUniformsDirty = false;
157321ba6478bb28924a634074f53d02c7b20f6dc1d5shannon.woods@transgaming.com
15748ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill    for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
15755929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com    {
1576834e8b7715c25e299c07c9d63f5be0a0ee6c5856Jamie Madill        const gl::LinkedUniform &uniform = *uniformArray[uniformIndex];
15775929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com
15788ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill        if (uniform.isReferencedByVertexShader() && !uniform.isSampler())
15795929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com        {
15808ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill            totalRegisterCountVS += uniform.registerCount;
15818ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill            vertexUniformsDirty = (vertexUniformsDirty || uniform.dirty);
15825929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com        }
15835929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com
15848ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill        if (uniform.isReferencedByFragmentShader() && !uniform.isSampler())
15855929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com        {
15868ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill            totalRegisterCountPS += uniform.registerCount;
15878ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill            pixelUniformsDirty = (pixelUniformsDirty || uniform.dirty);
15885929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com        }
15895929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com    }
15905929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com
15918ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill    const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getVertexUniformStorage());
15928ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill    const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getFragmentUniformStorage());
15938ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill    ASSERT(vertexUniformStorage);
15948ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill    ASSERT(fragmentUniformStorage);
15958ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill
15968ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill    ID3D11Buffer *vertexConstantBuffer = vertexUniformStorage->getConstantBuffer();
15978ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill    ID3D11Buffer *pixelConstantBuffer = fragmentUniformStorage->getConstantBuffer();
15985929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com
159909bf2a79d365082c12094a1f24dc9ff0b944a479shannon.woods@transgaming.com    float (*mapVS)[4] = NULL;
160009bf2a79d365082c12094a1f24dc9ff0b944a479shannon.woods@transgaming.com    float (*mapPS)[4] = NULL;
160109bf2a79d365082c12094a1f24dc9ff0b944a479shannon.woods@transgaming.com
16025ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods    if (totalRegisterCountVS > 0 && vertexUniformsDirty)
16035ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods    {
16045ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods        D3D11_MAPPED_SUBRESOURCE map = {0};
16055ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods        HRESULT result = mDeviceContext->Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
16069cd1915c96800fc998ec25b88b0e3081f0aa6109Geoff Lang        UNUSED_ASSERTION_VARIABLE(result);
16075ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods        ASSERT(SUCCEEDED(result));
16085ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods        mapVS = (float(*)[4])map.pData;
16095ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods    }
16105ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods
16115ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods    if (totalRegisterCountPS > 0 && pixelUniformsDirty)
16125ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods    {
16135ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods        D3D11_MAPPED_SUBRESOURCE map = {0};
16145ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods        HRESULT result = mDeviceContext->Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
16159cd1915c96800fc998ec25b88b0e3081f0aa6109Geoff Lang        UNUSED_ASSERTION_VARIABLE(result);
16165ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods        ASSERT(SUCCEEDED(result));
16175ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods        mapPS = (float(*)[4])map.pData;
16185ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods    }
1619873f28aaa55ee4a1c4c791de2bc209d4e0b72e64daniel@transgaming.com
16208ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill    for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
1621ab1c14629ce8af6bc76b29452e2677a8f0cdfc1adaniel@transgaming.com    {
1622834e8b7715c25e299c07c9d63f5be0a0ee6c5856Jamie Madill        gl::LinkedUniform *uniform = uniformArray[uniformIndex];
1623873f28aaa55ee4a1c4c791de2bc209d4e0b72e64daniel@transgaming.com
16248ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill        if (!uniform->isSampler())
1625873f28aaa55ee4a1c4c791de2bc209d4e0b72e64daniel@transgaming.com        {
16265b085dc344f1c7a54aa164c0db8eb7c9675f8c66Jamie Madill            unsigned int componentCount = (4 - uniform->registerElement);
16275b085dc344f1c7a54aa164c0db8eb7c9675f8c66Jamie Madill
162871cc91fcfc2832630e75c8152d1160208546624eJamie Madill            // we assume that uniforms from structs are arranged in struct order in our uniforms list. otherwise we would
16295b085dc344f1c7a54aa164c0db8eb7c9675f8c66Jamie Madill            // overwrite previously written regions of memory.
16305b085dc344f1c7a54aa164c0db8eb7c9675f8c66Jamie Madill
163138676dc14bd6136e9607e05825890ecf5cb402f1shannonwoods@chromium.org            if (uniform->isReferencedByVertexShader() && mapVS)
1632873f28aaa55ee4a1c4c791de2bc209d4e0b72e64daniel@transgaming.com            {
16335b085dc344f1c7a54aa164c0db8eb7c9675f8c66Jamie Madill                memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
1634e76b64b216e9f286210c6b1badd791909cca47bddaniel@transgaming.com            }
1635e76b64b216e9f286210c6b1badd791909cca47bddaniel@transgaming.com
163638676dc14bd6136e9607e05825890ecf5cb402f1shannonwoods@chromium.org            if (uniform->isReferencedByFragmentShader() && mapPS)
1637873f28aaa55ee4a1c4c791de2bc209d4e0b72e64daniel@transgaming.com            {
16385b085dc344f1c7a54aa164c0db8eb7c9675f8c66Jamie Madill                memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
1639e76b64b216e9f286210c6b1badd791909cca47bddaniel@transgaming.com            }
1640873f28aaa55ee4a1c4c791de2bc209d4e0b72e64daniel@transgaming.com        }
1641ab1c14629ce8af6bc76b29452e2677a8f0cdfc1adaniel@transgaming.com    }
1642873f28aaa55ee4a1c4c791de2bc209d4e0b72e64daniel@transgaming.com
164309bf2a79d365082c12094a1f24dc9ff0b944a479shannon.woods@transgaming.com    if (mapVS)
16445929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com    {
164509bf2a79d365082c12094a1f24dc9ff0b944a479shannon.woods@transgaming.com        mDeviceContext->Unmap(vertexConstantBuffer, 0);
16465929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com    }
16475929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com
164809bf2a79d365082c12094a1f24dc9ff0b944a479shannon.woods@transgaming.com    if (mapPS)
16495929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com    {
165009bf2a79d365082c12094a1f24dc9ff0b944a479shannon.woods@transgaming.com        mDeviceContext->Unmap(pixelConstantBuffer, 0);
16515929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com    }
1652c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang
1653c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    if (mCurrentVertexConstantBuffer != vertexConstantBuffer)
1654c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    {
1655c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang        mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer);
1656c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang        mCurrentVertexConstantBuffer = vertexConstantBuffer;
1657c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    }
1658c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang
1659c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    if (mCurrentPixelConstantBuffer != pixelConstantBuffer)
1660c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    {
1661c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang        mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer);
1662c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang        mCurrentPixelConstantBuffer = pixelConstantBuffer;
1663c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    }
16643e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com
1665a390e1eeeb5e990c9709ef5a4e80cd73f53f77c5daniel@transgaming.com    // Driver uniforms
16665fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    if (!mDriverConstantBufferVS)
16675fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    {
16685fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        D3D11_BUFFER_DESC constantBufferDescription = {0};
16695fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants);
16705fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
16715fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
16725fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        constantBufferDescription.CPUAccessFlags = 0;
16735fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        constantBufferDescription.MiscFlags = 0;
16745fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        constantBufferDescription.StructureByteStride = 0;
167546a5b87fbc06b70c3527831d5f2e3551604d9051shannon.woods@transgaming.com
16765929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com        HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferVS);
16779cd1915c96800fc998ec25b88b0e3081f0aa6109Geoff Lang        UNUSED_ASSERTION_VARIABLE(result);
16785fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        ASSERT(SUCCEEDED(result));
167946a5b87fbc06b70c3527831d5f2e3551604d9051shannon.woods@transgaming.com
16805fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        mDeviceContext->VSSetConstantBuffers(1, 1, &mDriverConstantBufferVS);
16815fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    }
1682a390e1eeeb5e990c9709ef5a4e80cd73f53f77c5daniel@transgaming.com
16835fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    if (!mDriverConstantBufferPS)
16845fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    {
16855fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        D3D11_BUFFER_DESC constantBufferDescription = {0};
16865fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants);
16875fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
16885fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
16895fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        constantBufferDescription.CPUAccessFlags = 0;
16905fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        constantBufferDescription.MiscFlags = 0;
16915fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        constantBufferDescription.StructureByteStride = 0;
169246a5b87fbc06b70c3527831d5f2e3551604d9051shannon.woods@transgaming.com
16935929ef275db34c11c6b0da8a5b56d9a6e2f431a0shannon.woods@transgaming.com        HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferPS);
16949cd1915c96800fc998ec25b88b0e3081f0aa6109Geoff Lang        UNUSED_ASSERTION_VARIABLE(result);
16955fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        ASSERT(SUCCEEDED(result));
1696873f28aaa55ee4a1c4c791de2bc209d4e0b72e64daniel@transgaming.com
16975fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS);
16985fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    }
169946a5b87fbc06b70c3527831d5f2e3551604d9051shannon.woods@transgaming.com
17005fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    if (memcmp(&mVertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0)
17015fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    {
17025fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &mVertexConstants, 16, 0);
17035fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        memcpy(&mAppliedVertexConstants, &mVertexConstants, sizeof(dx_VertexConstants));
17045fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    }
170546a5b87fbc06b70c3527831d5f2e3551604d9051shannon.woods@transgaming.com
17065fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    if (memcmp(&mPixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0)
17075fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    {
17085fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0);
17095fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com        memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants));
17105fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    }
17113e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com
17123e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com    // needed for the point sprite geometry shader
1713c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
1714c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    {
1715c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang        mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
1716c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang        mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
1717c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    }
1718ab1c14629ce8af6bc76b29452e2677a8f0cdfc1adaniel@transgaming.com}
1719ab1c14629ce8af6bc76b29452e2677a8f0cdfc1adaniel@transgaming.com
1720084a257ef7455c230fef3b3bc0cdeced4cabb1acdaniel@transgaming.comvoid Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
1721d084c620c0d275be03b10e1f802582dd278ff6fedaniel@transgaming.com{
1722da507fea063b882095bd54753cabc685ffdb575dGeoff Lang    mClear->clearFramebuffer(clearParams, frameBuffer);
172342477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    invalidateFramebufferSwizzles(frameBuffer);
172434f507ce49938eb1f3cd9e2780ea53a72795a20ashannon.woods@transgaming.com}
172534f507ce49938eb1f3cd9e2780ea53a72795a20ashannon.woods@transgaming.com
1726c43a60557d5e25cfb80cb0cd3c2a01920251745fdaniel@transgaming.comvoid Renderer11::markAllStateDirty()
1727c43a60557d5e25cfb80cb0cd3c2a01920251745fdaniel@transgaming.com{
1728f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com    for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
1729f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com    {
1730f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com        mAppliedRenderTargetSerials[rtIndex] = 0;
1731f4fe7105a58525321d5a03b084db08e8349bafd3shannon.woods%transgaming.com@gtempaccount.com    }
17329a067375601a2fb6f3d1cb66c49187fab7466a3edaniel@transgaming.com    mAppliedDepthbufferSerial = 0;
17339a067375601a2fb6f3d1cb66c49187fab7466a3edaniel@transgaming.com    mAppliedStencilbufferSerial = 0;
17347b6b83ea29cdea7c48f1bc3810bf66e60d9d2137daniel@transgaming.com    mDepthStencilInitialized = false;
17357b6b83ea29cdea7c48f1bc3810bf66e60d9d2137daniel@transgaming.com    mRenderTargetDescInitialized = false;
17367b6b83ea29cdea7c48f1bc3810bf66e60d9d2137daniel@transgaming.com
1737233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com    for (int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
173854de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com    {
173954de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        mForceSetVertexSamplerStates[i] = true;
174091382e555f35727043b6011e7f01fb2c74950fdbGeoff Lang        mCurVertexSRVs[i] = NULL;
174154de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com    }
174254de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com    for (int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++)
174354de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com    {
174454de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com        mForceSetPixelSamplerStates[i] = true;
174591382e555f35727043b6011e7f01fb2c74950fdbGeoff Lang        mCurPixelSRVs[i] = NULL;
174654de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com    }
174754de24f9b9d5752e5385d119c2a401b89800952ddaniel@transgaming.com
1748c43a60557d5e25cfb80cb0cd3c2a01920251745fdaniel@transgaming.com    mForceSetBlendState = true;
1749c43a60557d5e25cfb80cb0cd3c2a01920251745fdaniel@transgaming.com    mForceSetRasterState = true;
1750c43a60557d5e25cfb80cb0cd3c2a01920251745fdaniel@transgaming.com    mForceSetDepthStencilState = true;
1751c43a60557d5e25cfb80cb0cd3c2a01920251745fdaniel@transgaming.com    mForceSetScissor = true;
17525367004c2b297b872d37e64bc83c178c6d188d83daniel@transgaming.com    mForceSetViewport = true;
1753e499141632259ca0189c07c5eb947b728ff4ebbedaniel@transgaming.com
17547840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang    mAppliedIB = NULL;
17557840b170f1f4b34cda8295c83f0f59825511f667Geoff Lang    mAppliedIBFormat = DXGI_FORMAT_UNKNOWN;
17567fbf486e4bf16530f84a88fa139641d82b334254daniel@transgaming.com    mAppliedIBOffset = 0;
17577fbf486e4bf16530f84a88fa139641d82b334254daniel@transgaming.com
17586246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    mAppliedVertexShader = NULL;
17596246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    mAppliedGeometryShader = NULL;
17604c5c6bbb82f96de2d3abe0c7c7c7d72fba5217c9Geoff Lang    mCurPointGeometryShader = NULL;
17616246dc8fecf658cd200a33aa15c7677054daa0d3Jamie Madill    mAppliedPixelShader = NULL;
1762eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang
1763eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang    for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
1764eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang    {
1765eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        mAppliedTFBuffers[i] = NULL;
1766eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang        mAppliedTFOffsets[i] = 0;
1767eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang    }
1768eeba6e1e88a04ab30db442c2af77bf53034ef332Geoff Lang
17695fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants));
17705fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com    memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants));
17711f53cab03db7b06d9cc6d90bdb0350ed9554046bGeoff Lang
17721f53cab03db7b06d9cc6d90bdb0350ed9554046bGeoff Lang    mInputLayoutCache.markDirty();
1773c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang
1774c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; i++)
1775c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    {
1776c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang        mCurrentConstantBufferVS[i] = -1;
1777c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang        mCurrentConstantBufferPS[i] = -1;
1778c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    }
1779c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang
1780c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    mCurrentVertexConstantBuffer = NULL;
1781c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    mCurrentPixelConstantBuffer = NULL;
1782c6354ee5882512fc09e7be42e243f91b994fd512Geoff Lang    mCurrentGeometryConstantBuffer = NULL;
17834c09586e7c8ebff631e4c459fc5701a0c95e9693Geoff Lang
17844c09586e7c8ebff631e4c459fc5701a0c95e9693Geoff Lang    mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
1785c43a60557d5e25cfb80cb0cd3c2a01920251745fdaniel@transgaming.com}
1786c43a60557d5e25cfb80cb0cd3c2a01920251745fdaniel@transgaming.com
17871d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comvoid Renderer11::releaseDeviceResources()
17881d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
1789f8ba1091ee5c252c430d56256d3fd081ae98689bdaniel@transgaming.com    mStateCache.clear();
1790c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com    mInputLayoutCache.clear();
1791c5431eb29f8ffa0088b750139802fceb31e1cc33daniel@transgaming.com
1792ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeDelete(mVertexDataManager);
1793ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeDelete(mIndexDataManager);
1794ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeDelete(mLineLoopIB);
1795ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeDelete(mTriangleFanIB);
1796ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeDelete(mBlit);
1797da507fea063b882095bd54753cabc685ffdb575dGeoff Lang    SafeDelete(mClear);
1798a21eea36fbb03d7d680ca7f472fcf96b1bbc1f63Jamie Madill    SafeDelete(mPixelTransfer);
17995fb979d55dfac1f6509ac6d10bc8fa22719bcc29shannon.woods@transgaming.com
1800894b324ff711a16f4ad827f26e59e3b5c3b2e2adshannonwoods@chromium.org    SafeRelease(mDriverConstantBufferVS);
1801894b324ff711a16f4ad827f26e59e3b5c3b2e2adshannonwoods@chromium.org    SafeRelease(mDriverConstantBufferPS);
1802894b324ff711a16f4ad827f26e59e3b5c3b2e2adshannonwoods@chromium.org    SafeRelease(mSyncQuery);
18031d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
18041d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
1805eb049e2c2de52176f2a755460d421889fda9ed19shannon.woods@transgaming.comvoid Renderer11::notifyDeviceLost()
18061d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
18071d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    mDeviceLost = true;
1808eb049e2c2de52176f2a755460d421889fda9ed19shannon.woods@transgaming.com    mDisplay->notifyDeviceLost();
18091d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
18101d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
18111d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.combool Renderer11::isDeviceLost()
18121d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
18131d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    return mDeviceLost;
18141d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
18151d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
18161d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com// set notify to true to broadcast a message to all contexts of the device loss
18171d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.combool Renderer11::testDeviceLost(bool notify)
18181d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
18191d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    bool isLost = false;
18201d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
1821ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    // GetRemovedReason is used to test if the device is removed
1822ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    HRESULT result = mDevice->GetDeviceRemovedReason();
1823ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    isLost = d3d11::isDeviceLostError(result);
18241d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
18251d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    if (isLost)
18261d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    {
1827ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        // Log error if this is a new device lost event
1828ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        if (mDeviceLost == false)
1829ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        {
1830ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com            ERR("The D3D11 device was removed: 0x%08X", result);
1831ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        }
1832ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com
18331d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com        // ensure we note the device loss --
1834779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        // we'll probably get this done again by notifyDeviceLost
1835779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        // but best to remember it!
18361d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com        // Note that we don't want to clear the device loss status here
18371d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com        // -- this needs to be done by resetDevice
18381d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com        mDeviceLost = true;
18391d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com        if (notify)
18401d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com        {
1841eb049e2c2de52176f2a755460d421889fda9ed19shannon.woods@transgaming.com            notifyDeviceLost();
18421d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com        }
18431d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    }
18441d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
18451d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    return isLost;
18461d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
18471d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
18481d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.combool Renderer11::testDeviceResettable()
18491d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
1850ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    // determine if the device is resettable by creating a dummy device
1851ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
18521d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
1853ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    if (D3D11CreateDevice == NULL)
1854ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    {
1855ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        return false;
1856ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    }
18571d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
1858d438fd497baeddedec135e7c8bfa4148e116b9a8shannon.woods@transgaming.com    D3D_FEATURE_LEVEL featureLevels[] =
1859ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    {
1860ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        D3D_FEATURE_LEVEL_11_0,
1861ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        D3D_FEATURE_LEVEL_10_1,
1862ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        D3D_FEATURE_LEVEL_10_0,
1863ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    };
1864ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com
1865ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    ID3D11Device* dummyDevice;
1866ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    D3D_FEATURE_LEVEL dummyFeatureLevel;
1867ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    ID3D11DeviceContext* dummyContext;
1868ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com
1869ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    HRESULT result = D3D11CreateDevice(NULL,
1870ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com                                       D3D_DRIVER_TYPE_HARDWARE,
1871ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com                                       NULL,
1872ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com                                       #if defined(_DEBUG)
1873ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com                                       D3D11_CREATE_DEVICE_DEBUG,
1874ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com                                       #else
1875ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com                                       0,
1876ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com                                       #endif
1877d438fd497baeddedec135e7c8bfa4148e116b9a8shannon.woods@transgaming.com                                       featureLevels,
1878d438fd497baeddedec135e7c8bfa4148e116b9a8shannon.woods@transgaming.com                                       ArraySize(featureLevels),
1879ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com                                       D3D11_SDK_VERSION,
1880ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com                                       &dummyDevice,
1881ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com                                       &dummyFeatureLevel,
1882ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com                                       &dummyContext);
1883ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com
1884ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    if (!mDevice || FAILED(result))
18851d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    {
18861d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com        return false;
18871d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    }
1888ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com
1889ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(dummyContext);
1890ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(dummyDevice);
1891ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com
1892ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    return true;
18931d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
18941d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
1895ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.comvoid Renderer11::release()
18961d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
18971d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    releaseDeviceResources();
18981d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
1899ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(mDxgiFactory);
1900ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(mDxgiAdapter);
1901ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com
1902ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    if (mDeviceContext)
1903ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    {
1904ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        mDeviceContext->ClearState();
1905ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        mDeviceContext->Flush();
1906ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(mDeviceContext);
1907ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    }
1908ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com
1909ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(mDevice);
1910ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com
1911ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    if (mD3d11Module)
1912ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    {
1913ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        FreeLibrary(mD3d11Module);
1914ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        mD3d11Module = NULL;
1915ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    }
1916ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com
1917ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    if (mDxgiModule)
1918ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    {
1919ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        FreeLibrary(mDxgiModule);
1920ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        mDxgiModule = NULL;
1921ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    }
1922dad5ed3953e4f31c35b9fd67901fb78dbe140dd0Geoff Lang
1923dad5ed3953e4f31c35b9fd67901fb78dbe140dd0Geoff Lang    mCompiler.release();
1924ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com}
1925ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com
1926ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.combool Renderer11::resetDevice()
1927ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com{
1928ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    // recreate everything
1929ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    release();
1930ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    EGLint result = initialize();
1931ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com
1932ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    if (result != EGL_SUCCESS)
1933ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    {
1934ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        ERR("Could not reinitialize D3D11 device: %08X", result);
1935ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        return false;
1936ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com    }
19371d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
19381d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    mDeviceLost = false;
19391d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
19401d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    return true;
19411d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
19421d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
19431d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comDWORD Renderer11::getAdapterVendor() const
19441d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
19451f811f55df504216a4d6c5e0921110639f138ac9daniel@transgaming.com    return mAdapterDescription.VendorId;
19461d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
19471d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
1948ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.comstd::string Renderer11::getRendererDescription() const
19491d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
1950ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com    std::ostringstream rendererString;
1951ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com
1952ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com    rendererString << mDescription;
1953ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com    rendererString << " Direct3D11";
1954ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com
1955ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com    rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel();
1956ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com    rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel();
1957ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com
1958ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com    return rendererString.str();
19591d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
19601d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
19611d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comGUID Renderer11::getAdapterIdentifier() const
19621d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
196343db7955ed8268d63a53ec3b70c714d32c1d7bd6shannon.woods@transgaming.com    // Use the adapter LUID as our adapter ID
196443db7955ed8268d63a53ec3b70c714d32c1d7bd6shannon.woods@transgaming.com    // This number is local to a machine is only guaranteed to be unique between restarts
196543db7955ed8268d63a53ec3b70c714d32c1d7bd6shannon.woods@transgaming.com    META_ASSERT(sizeof(LUID) <= sizeof(GUID));
196643db7955ed8268d63a53ec3b70c714d32c1d7bd6shannon.woods@transgaming.com    GUID adapterId = {0};
196743db7955ed8268d63a53ec3b70c714d32c1d7bd6shannon.woods@transgaming.com    memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID));
196843db7955ed8268d63a53ec3b70c714d32c1d7bd6shannon.woods@transgaming.com    return adapterId;
19691d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
19701d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
1971bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.combool Renderer11::getBGRATextureSupport() const
1972bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com{
1973bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com    return mBGRATextureSupport;
1974bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com}
1975bec04bf43b2603f33a84c6eb6b6fa4b13ad10161shannon.woods@transgaming.com
197689200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.orgbool Renderer11::getDXT1TextureSupport() const
19771d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
197809f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    return mDXT1TextureSupport;
19791d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
19801d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
198189200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.orgbool Renderer11::getDXT3TextureSupport() const
19821d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
198309f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    return mDXT3TextureSupport;
19841d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
19851d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
198689200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.orgbool Renderer11::getDXT5TextureSupport() const
19871d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
198809f326b0e79447d84e791c6611858e0ba67c41a5shannon.woods@transgaming.com    return mDXT5TextureSupport;
19891d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
19901d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
19911d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.combool Renderer11::getDepthTextureSupport() const
19921d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
1993cf103f361c2ae24183f0bfd323303a97196a34d5shannon.woods@transgaming.com    return mDepthTextureSupport;
19941d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
19951d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
199689200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.orgbool Renderer11::getFloat32TextureSupport() const
19971d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
19989cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    return mFloat32TextureSupport;
19991d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
20001d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
200189200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.orgbool Renderer11::getFloat32TextureFilteringSupport() const
200289200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org{
200389200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org    return mFloat32FilterSupport;
200489200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org}
200589200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org
200689200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.orgbool Renderer11::getFloat32TextureRenderingSupport() const
200789200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org{
200889200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org    return mFloat32RenderSupport;
200989200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org}
201089200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org
201189200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.orgbool Renderer11::getFloat16TextureSupport() const
20121d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
20139cdced65768f4f4ee407768433e824aa385a2b18shannon.woods@transgaming.com    return mFloat16TextureSupport;
20141d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
20151d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
201689200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.orgbool Renderer11::getFloat16TextureFilteringSupport() const
201789200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org{
201889200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org    return mFloat16FilterSupport;
201989200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org}
202089200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org
202189200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.orgbool Renderer11::getFloat16TextureRenderingSupport() const
202289200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org{
202389200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org    return mFloat16RenderSupport;
202489200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org}
202589200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.org
2026d42cf4ed18e40ae397ebf5e2a0aea844c70eec95Geoff Langbool Renderer11::getRGB565TextureSupport() const
2027d42cf4ed18e40ae397ebf5e2a0aea844c70eec95Geoff Lang{
2028d42cf4ed18e40ae397ebf5e2a0aea844c70eec95Geoff Lang    return false;
2029d42cf4ed18e40ae397ebf5e2a0aea844c70eec95Geoff Lang}
2030d42cf4ed18e40ae397ebf5e2a0aea844c70eec95Geoff Lang
203189200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.orgbool Renderer11::getLuminanceTextureSupport() const
20321d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
20331d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    return false;
20341d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
20351d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
203689200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.orgbool Renderer11::getLuminanceAlphaTextureSupport() const
20371d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
20381d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    return false;
20391d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
20401d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
2041632192dd8098d303fbf4d66f5d61c7363039a818Geoff Langbool Renderer11::getRGTextureSupport() const
2042632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang{
2043632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang    return mRGTextureSupport;
2044632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang}
2045632192dd8098d303fbf4d66f5d61c7363039a818Geoff Lang
20461d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.combool Renderer11::getTextureFilterAnisotropySupport() const
20471d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
20481abd7974e2759faa46794f6e542738d3d809ce27shannon.woods@transgaming.com    return true;
20491d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
20501d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
2051b3801744ed9df17a7d8d290e203938818ad90addShannon Woodsbool Renderer11::getPBOSupport() const
2052b3801744ed9df17a7d8d290e203938818ad90addShannon Woods{
2053b3801744ed9df17a7d8d290e203938818ad90addShannon Woods    return true;
2054b3801744ed9df17a7d8d290e203938818ad90addShannon Woods}
2055b3801744ed9df17a7d8d290e203938818ad90addShannon Woods
20561d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comfloat Renderer11::getTextureMaxAnisotropy() const
20571d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
20581abd7974e2759faa46794f6e542738d3d809ce27shannon.woods@transgaming.com    switch (mFeatureLevel)
20591abd7974e2759faa46794f6e542738d3d809ce27shannon.woods@transgaming.com    {
20601abd7974e2759faa46794f6e542738d3d809ce27shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_11_0:
20611abd7974e2759faa46794f6e542738d3d809ce27shannon.woods@transgaming.com        return D3D11_MAX_MAXANISOTROPY;
20621abd7974e2759faa46794f6e542738d3d809ce27shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_1:
20631abd7974e2759faa46794f6e542738d3d809ce27shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_0:
20641abd7974e2759faa46794f6e542738d3d809ce27shannon.woods@transgaming.com        return D3D10_MAX_MAXANISOTROPY;
20651abd7974e2759faa46794f6e542738d3d809ce27shannon.woods@transgaming.com      default: UNREACHABLE();
20661abd7974e2759faa46794f6e542738d3d809ce27shannon.woods@transgaming.com        return 0;
20671abd7974e2759faa46794f6e542738d3d809ce27shannon.woods@transgaming.com    }
20681d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
20691d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
207089200d93b4b524cac319b66ac135b3f7e84f9227shannonwoods@chromium.orgbool Renderer11::getEventQuerySupport() const
20711d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
2072be58aa08c2867e3483afb6313c5c06cf35c724d4shannon.woods@transgaming.com    return true;
20731d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
20741d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
20758ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.comRange Renderer11::getViewportBounds() const
20768ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com{
20778ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    switch (mFeatureLevel)
20788ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    {
20798ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_11_0:
20808ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com        return Range(D3D11_VIEWPORT_BOUNDS_MIN, D3D11_VIEWPORT_BOUNDS_MAX);
20818ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_1:
20828ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_0:
20838ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com        return Range(D3D10_VIEWPORT_BOUNDS_MIN, D3D10_VIEWPORT_BOUNDS_MAX);
20848ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com      default: UNREACHABLE();
20858ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com        return Range(0, 0);
20868ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    }
20878ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com}
20888ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com
2089233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.comunsigned int Renderer11::getMaxVertexTextureImageUnits() const
20901d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
2091233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com    META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
2092233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com    switch (mFeatureLevel)
2093233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com    {
2094233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_11_0:
2095233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_1:
2096233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_0:
2097233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com        return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4;
2098233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com      default: UNREACHABLE();
2099233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com        return 0;
2100233fe9548a2b166d3ccb09a4a7af273fab6dbf2cshannon.woods@transgaming.com    }
21011d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
21021d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
210376cd88c5a67c14da7f4e0a7a6491297e3fb49bcbshannon.woods@transgaming.comunsigned int Renderer11::getMaxCombinedTextureImageUnits() const
210476cd88c5a67c14da7f4e0a7a6491297e3fb49bcbshannon.woods@transgaming.com{
210576cd88c5a67c14da7f4e0a7a6491297e3fb49bcbshannon.woods@transgaming.com    return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits();
210676cd88c5a67c14da7f4e0a7a6491297e3fb49bcbshannon.woods@transgaming.com}
210776cd88c5a67c14da7f4e0a7a6491297e3fb49bcbshannon.woods@transgaming.com
2108d8136cbbc2a2d9249ef1acad54fb875fe521eee5shannon.woods@transgaming.comunsigned int Renderer11::getReservedVertexUniformVectors() const
2109d8136cbbc2a2d9249ef1acad54fb875fe521eee5shannon.woods@transgaming.com{
21105ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods    return 0;   // Driver uniforms are stored in a separate constant buffer
2111d8136cbbc2a2d9249ef1acad54fb875fe521eee5shannon.woods@transgaming.com}
2112d8136cbbc2a2d9249ef1acad54fb875fe521eee5shannon.woods@transgaming.com
2113d8136cbbc2a2d9249ef1acad54fb875fe521eee5shannon.woods@transgaming.comunsigned int Renderer11::getReservedFragmentUniformVectors() const
2114d8136cbbc2a2d9249ef1acad54fb875fe521eee5shannon.woods@transgaming.com{
21155ab33c89000085158a5b7806560131bbf7fa0e55Shannon Woods    return 0;   // Driver uniforms are stored in a separate constant buffer
2116d8136cbbc2a2d9249ef1acad54fb875fe521eee5shannon.woods@transgaming.com}
2117d8136cbbc2a2d9249ef1acad54fb875fe521eee5shannon.woods@transgaming.com
2118d8136cbbc2a2d9249ef1acad54fb875fe521eee5shannon.woods@transgaming.comunsigned int Renderer11::getMaxVertexUniformVectors() const
2119254317da1b997a0f73b297b8b100116879a8e7a6shannon.woods@transgaming.com{
21204e48204afe732c1ad739b73867500d11552b6e4fshannon.woods@transgaming.com    META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
21214e48204afe732c1ad739b73867500d11552b6e4fshannon.woods@transgaming.com    ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
21224e48204afe732c1ad739b73867500d11552b6e4fshannon.woods@transgaming.com    return MAX_VERTEX_UNIFORM_VECTORS_D3D11;
2123254317da1b997a0f73b297b8b100116879a8e7a6shannon.woods@transgaming.com}
2124254317da1b997a0f73b297b8b100116879a8e7a6shannon.woods@transgaming.com
2125d8136cbbc2a2d9249ef1acad54fb875fe521eee5shannon.woods@transgaming.comunsigned int Renderer11::getMaxFragmentUniformVectors() const
2126254317da1b997a0f73b297b8b100116879a8e7a6shannon.woods@transgaming.com{
21274e48204afe732c1ad739b73867500d11552b6e4fshannon.woods@transgaming.com    META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
21284e48204afe732c1ad739b73867500d11552b6e4fshannon.woods@transgaming.com    ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
21294e48204afe732c1ad739b73867500d11552b6e4fshannon.woods@transgaming.com    return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11;
2130254317da1b997a0f73b297b8b100116879a8e7a6shannon.woods@transgaming.com}
2131254317da1b997a0f73b297b8b100116879a8e7a6shannon.woods@transgaming.com
2132d8136cbbc2a2d9249ef1acad54fb875fe521eee5shannon.woods@transgaming.comunsigned int Renderer11::getMaxVaryingVectors() const
213328d268ea21d334ffcdc6fb573793430c848c8ddashannon.woods@transgaming.com{
213428d268ea21d334ffcdc6fb573793430c848c8ddashannon.woods@transgaming.com    META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
213574b86cffade4b3dbfddd3c601b35b87ef28a82a6shannonwoods@chromium.org    META_ASSERT(D3D11_VS_OUTPUT_REGISTER_COUNT <= D3D11_PS_INPUT_REGISTER_COUNT);
213674b86cffade4b3dbfddd3c601b35b87ef28a82a6shannonwoods@chromium.org    META_ASSERT(D3D10_VS_OUTPUT_REGISTER_COUNT <= D3D10_PS_INPUT_REGISTER_COUNT);
213728d268ea21d334ffcdc6fb573793430c848c8ddashannon.woods@transgaming.com    switch (mFeatureLevel)
213828d268ea21d334ffcdc6fb573793430c848c8ddashannon.woods@transgaming.com    {
213928d268ea21d334ffcdc6fb573793430c848c8ddashannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_11_0:
21401b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang        return D3D11_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings();
214128d268ea21d334ffcdc6fb573793430c848c8ddashannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_1:
21421b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang        return D3D10_1_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings();
214328d268ea21d334ffcdc6fb573793430c848c8ddashannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_0:
21441b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang        return D3D10_VS_OUTPUT_REGISTER_COUNT - getReservedVaryings();
214528d268ea21d334ffcdc6fb573793430c848c8ddashannon.woods@transgaming.com      default: UNREACHABLE();
214628d268ea21d334ffcdc6fb573793430c848c8ddashannon.woods@transgaming.com        return 0;
214728d268ea21d334ffcdc6fb573793430c848c8ddashannon.woods@transgaming.com    }
214828d268ea21d334ffcdc6fb573793430c848c8ddashannon.woods@transgaming.com}
214928d268ea21d334ffcdc6fb573793430c848c8ddashannon.woods@transgaming.com
21503f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.comunsigned int Renderer11::getMaxVertexShaderUniformBuffers() const
21513f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com{
215234089354b04a78dc6a6c0bda15b4757a8f9a0401shannon.woods%transgaming.com@gtempaccount.com    META_ASSERT(gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS >= D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT &&
215334089354b04a78dc6a6c0bda15b4757a8f9a0401shannon.woods%transgaming.com@gtempaccount.com                gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
215434089354b04a78dc6a6c0bda15b4757a8f9a0401shannon.woods%transgaming.com@gtempaccount.com
21553f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com    switch (mFeatureLevel)
21563f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com    {
21573f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_11_0:
21582b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org        return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedVertexUniformBuffers();
21593f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_10_1:
21603f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_10_0:
21612b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org        return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedVertexUniformBuffers();
21623f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com      default: UNREACHABLE();
21633f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com        return 0;
21643f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com    }
21653f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com}
21663f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com
21673f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.comunsigned int Renderer11::getMaxFragmentShaderUniformBuffers() const
21683f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com{
216934089354b04a78dc6a6c0bda15b4757a8f9a0401shannon.woods%transgaming.com@gtempaccount.com    META_ASSERT(gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS >= D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT &&
217034089354b04a78dc6a6c0bda15b4757a8f9a0401shannon.woods%transgaming.com@gtempaccount.com                gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
217134089354b04a78dc6a6c0bda15b4757a8f9a0401shannon.woods%transgaming.com@gtempaccount.com
21723f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com    switch (mFeatureLevel)
21733f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com    {
21743f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_11_0:
21752b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org        return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedFragmentUniformBuffers();
21763f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_10_1:
21773f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_10_0:
21782b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org        return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - getReservedFragmentUniformBuffers();
21793f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com      default: UNREACHABLE();
21803f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com        return 0;
21813f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com    }
21823f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com}
21833f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com
21842b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.orgunsigned int Renderer11::getReservedVertexUniformBuffers() const
21852b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org{
21862b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org    // we reserve one buffer for the application uniforms, and one for driver uniforms
21872b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org    return 2;
21882b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org}
21892b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org
21902b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.orgunsigned int Renderer11::getReservedFragmentUniformBuffers() const
21912b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org{
21922b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org    // we reserve one buffer for the application uniforms, and one for driver uniforms
21932b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org    return 2;
21942b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org}
21952b5442236b5acaa150e1a608fa7c97c5e1b2e19eshannonwoods@chromium.org
21961b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Langunsigned int Renderer11::getReservedVaryings() const
21971b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang{
21981b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang    // We potentially reserve varyings for gl_Position, _dx_Position, gl_FragCoord and gl_PointSize
21991b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang    return 4;
22001b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang}
22011b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang
22021b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang
22033f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.comunsigned int Renderer11::getMaxTransformFeedbackBuffers() const
22043f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com{
220534089354b04a78dc6a6c0bda15b4757a8f9a0401shannon.woods%transgaming.com@gtempaccount.com    META_ASSERT(gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS >= D3D11_SO_BUFFER_SLOT_COUNT &&
220634089354b04a78dc6a6c0bda15b4757a8f9a0401shannon.woods%transgaming.com@gtempaccount.com                gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS >= D3D10_SO_BUFFER_SLOT_COUNT);
220734089354b04a78dc6a6c0bda15b4757a8f9a0401shannon.woods%transgaming.com@gtempaccount.com
22083f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com    switch (mFeatureLevel)
22093f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com    {
22103f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_11_0:
22113f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com        return D3D11_SO_BUFFER_SLOT_COUNT;
22123f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_10_1:
22131b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang        return D3D10_1_SO_BUFFER_SLOT_COUNT;
22143f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_10_0:
22153f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com        return D3D10_SO_BUFFER_SLOT_COUNT;
22163f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com      default: UNREACHABLE();
22173f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com        return 0;
22183f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com    }
22193f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com}
22203f72ce3511d7a4a4272ea13ebfdc473f8698074cshannon.woods%transgaming.com@gtempaccount.com
22211b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Langunsigned int Renderer11::getMaxTransformFeedbackSeparateComponents() const
22221b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang{
22231b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang    switch (mFeatureLevel)
22241b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang    {
22251b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang      case D3D_FEATURE_LEVEL_11_0:
22261b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang        return getMaxTransformFeedbackInterleavedComponents() / getMaxTransformFeedbackBuffers();
22271b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang      case D3D_FEATURE_LEVEL_10_1:
22281b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang      case D3D_FEATURE_LEVEL_10_0:
22291b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang        // D3D 10 and 10.1 only allow one output per output slot if an output slot other than zero
22301b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang        // is used.
22311b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang        return 4;
22321b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang      default: UNREACHABLE();
22331b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang        return 0;
22341b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang    }
22351b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang}
22361b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang
22371b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Langunsigned int Renderer11::getMaxTransformFeedbackInterleavedComponents() const
22381b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang{
22391b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang    return (getMaxVaryingVectors() * 4);
22401b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang}
22411b6edcb636b4ed9c473cca9774c5784768f7d346Geoff Lang
224233e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.orgunsigned int Renderer11::getMaxUniformBufferSize() const
224333e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org{
224433e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org    // Each component is a 4-element vector of 4-byte units (floats)
224533e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org    const unsigned int bytesPerComponent = 4 * sizeof(float);
224633e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org
224733e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org    switch (mFeatureLevel)
224833e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org    {
224933e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org      case D3D_FEATURE_LEVEL_11_0:
225033e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org        return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
225133e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org      case D3D_FEATURE_LEVEL_10_1:
225233e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org      case D3D_FEATURE_LEVEL_10_0:
225333e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org        return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
225433e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org      default: UNREACHABLE();
225533e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org        return 0;
225633e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org    }
225733e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org}
225833e798f5e64d758f31edeb75418fd887e44cca48shannonwoods@chromium.org
22591d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.combool Renderer11::getNonPower2TextureSupport() const
22601d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
226103951cf9a040453111dc4b312bf276aee7337ea6shannon.woods@transgaming.com    switch (mFeatureLevel)
226203951cf9a040453111dc4b312bf276aee7337ea6shannon.woods@transgaming.com    {
226303951cf9a040453111dc4b312bf276aee7337ea6shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_11_0:
226403951cf9a040453111dc4b312bf276aee7337ea6shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_1:
226503951cf9a040453111dc4b312bf276aee7337ea6shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_0:
226603951cf9a040453111dc4b312bf276aee7337ea6shannon.woods@transgaming.com        return true;
226703951cf9a040453111dc4b312bf276aee7337ea6shannon.woods@transgaming.com      default: UNREACHABLE();
226803951cf9a040453111dc4b312bf276aee7337ea6shannon.woods@transgaming.com        return false;
226903951cf9a040453111dc4b312bf276aee7337ea6shannon.woods@transgaming.com    }
22701d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
22711d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
22721d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.combool Renderer11::getOcclusionQuerySupport() const
22731d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
22748b7606aad42b7eb5a183b502902106f9ba6f7ac4shannon.woods@transgaming.com    switch (mFeatureLevel)
22758b7606aad42b7eb5a183b502902106f9ba6f7ac4shannon.woods@transgaming.com    {
22768b7606aad42b7eb5a183b502902106f9ba6f7ac4shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_11_0:
22778b7606aad42b7eb5a183b502902106f9ba6f7ac4shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_1:
22788b7606aad42b7eb5a183b502902106f9ba6f7ac4shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_0:
22798b7606aad42b7eb5a183b502902106f9ba6f7ac4shannon.woods@transgaming.com        return true;
22808b7606aad42b7eb5a183b502902106f9ba6f7ac4shannon.woods@transgaming.com      default: UNREACHABLE();
22818b7606aad42b7eb5a183b502902106f9ba6f7ac4shannon.woods@transgaming.com        return false;
22828b7606aad42b7eb5a183b502902106f9ba6f7ac4shannon.woods@transgaming.com    }
22831d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
22841d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
22851d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.combool Renderer11::getInstancingSupport() const
22861d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
2287fe3246411e6c1e9adefa11075dfaa3deb2855c90daniel@transgaming.com    switch (mFeatureLevel)
2288fe3246411e6c1e9adefa11075dfaa3deb2855c90daniel@transgaming.com    {
2289fe3246411e6c1e9adefa11075dfaa3deb2855c90daniel@transgaming.com      case D3D_FEATURE_LEVEL_11_0:
2290fe3246411e6c1e9adefa11075dfaa3deb2855c90daniel@transgaming.com      case D3D_FEATURE_LEVEL_10_1:
2291fe3246411e6c1e9adefa11075dfaa3deb2855c90daniel@transgaming.com      case D3D_FEATURE_LEVEL_10_0:
2292fe3246411e6c1e9adefa11075dfaa3deb2855c90daniel@transgaming.com        return true;
2293fe3246411e6c1e9adefa11075dfaa3deb2855c90daniel@transgaming.com      default: UNREACHABLE();
2294fe3246411e6c1e9adefa11075dfaa3deb2855c90daniel@transgaming.com        return false;
2295fe3246411e6c1e9adefa11075dfaa3deb2855c90daniel@transgaming.com    }
22961d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
22971d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
22981d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.combool Renderer11::getShareHandleSupport() const
22991d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
2300c60c5215ebab426654d1670282d15652667e38dashannon.woods@transgaming.com    // We only currently support share handles with BGRA surfaces, because
2301c60c5215ebab426654d1670282d15652667e38dashannon.woods@transgaming.com    // chrome needs BGRA. Once chrome fixes this, we should always support them.
23021d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com    // PIX doesn't seem to support using share handles, so disable them.
2303c60c5215ebab426654d1670282d15652667e38dashannon.woods@transgaming.com    return getBGRATextureSupport() && !gl::perfActive();
23041d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
23051d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
23067629bb6c10907e6aae1710eafd15306d43c1840edaniel@transgaming.combool Renderer11::getDerivativeInstructionSupport() const
23077629bb6c10907e6aae1710eafd15306d43c1840edaniel@transgaming.com{
230809fd9458bc98f31fcd2820dd3fd24bc7114ff56fshannon.woods@transgaming.com    switch (mFeatureLevel)
230909fd9458bc98f31fcd2820dd3fd24bc7114ff56fshannon.woods@transgaming.com    {
231009fd9458bc98f31fcd2820dd3fd24bc7114ff56fshannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_11_0:
231109fd9458bc98f31fcd2820dd3fd24bc7114ff56fshannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_1:
231209fd9458bc98f31fcd2820dd3fd24bc7114ff56fshannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_0:
231309fd9458bc98f31fcd2820dd3fd24bc7114ff56fshannon.woods@transgaming.com        return true;
231409fd9458bc98f31fcd2820dd3fd24bc7114ff56fshannon.woods@transgaming.com      default: UNREACHABLE();
231509fd9458bc98f31fcd2820dd3fd24bc7114ff56fshannon.woods@transgaming.com        return false;
231609fd9458bc98f31fcd2820dd3fd24bc7114ff56fshannon.woods@transgaming.com    }
23177629bb6c10907e6aae1710eafd15306d43c1840edaniel@transgaming.com}
23187629bb6c10907e6aae1710eafd15306d43c1840edaniel@transgaming.com
23198d2f086ad33f82aa1a01fe86a1bbfa6eba47e224shannon.woods@transgaming.combool Renderer11::getPostSubBufferSupport() const
23208d2f086ad33f82aa1a01fe86a1bbfa6eba47e224shannon.woods@transgaming.com{
23218d2f086ad33f82aa1a01fe86a1bbfa6eba47e224shannon.woods@transgaming.com    // D3D11 does not support present with dirty rectangles until D3D11.1 and DXGI 1.2.
23228d2f086ad33f82aa1a01fe86a1bbfa6eba47e224shannon.woods@transgaming.com    return false;
23238d2f086ad33f82aa1a01fe86a1bbfa6eba47e224shannon.woods@transgaming.com}
23248d2f086ad33f82aa1a01fe86a1bbfa6eba47e224shannon.woods@transgaming.com
232513a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madillint Renderer11::getMaxRecommendedElementsIndices() const
232613a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill{
232713a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill    META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
232813a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill    META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
232913a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill
233013a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill    // D3D11 allows up to 2^32 elements, but we report max signed int for convenience.
233113a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill    return std::numeric_limits<GLint>::max();
233213a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill}
233313a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill
233413a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madillint Renderer11::getMaxRecommendedElementsVertices() const
233513a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill{
233613a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill    META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
233713a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill    META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
233813a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill
233913a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill    // D3D11 allows up to 2^32 elements, but we report max signed int for convenience.
234013a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill    return std::numeric_limits<GLint>::max();
234113a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill}
234213a2f85b8d01c1685d1835bd7f7d734eb13ae60fJamie Madill
23439549bead5dc8bb07a21296ea8bea97939285c699daniel@transgaming.comint Renderer11::getMajorShaderModel() const
23441d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
23459549bead5dc8bb07a21296ea8bea97939285c699daniel@transgaming.com    switch (mFeatureLevel)
23469549bead5dc8bb07a21296ea8bea97939285c699daniel@transgaming.com    {
23479549bead5dc8bb07a21296ea8bea97939285c699daniel@transgaming.com      case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION;   // 5
2348ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com      case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4
23499549bead5dc8bb07a21296ea8bea97939285c699daniel@transgaming.com      case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION;   // 4
23509549bead5dc8bb07a21296ea8bea97939285c699daniel@transgaming.com      default: UNREACHABLE();      return 0;
23519549bead5dc8bb07a21296ea8bea97939285c699daniel@transgaming.com    }
23521d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
23531d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
2354ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.comint Renderer11::getMinorShaderModel() const
2355ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com{
2356ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com    switch (mFeatureLevel)
2357ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com    {
2358ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com      case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION;   // 0
2359ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com      case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1
2360ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com      case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION;   // 0
2361ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com      default: UNREACHABLE();      return 0;
2362ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com    }
2363ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com}
2364ca1ac1f113e18815bab14a3465039bd57b41c10ddaniel@transgaming.com
23651d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comfloat Renderer11::getMaxPointSize() const
23661d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
23673e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com    // choose a reasonable maximum. we enforce this in the shader.
23683e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com    // (nb: on a Radeon 2600xt, DX9 reports a 256 max point size)
23693e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com    return 1024.0f;
23701d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
23711d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
23728ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.comint Renderer11::getMaxViewportDimension() const
23738ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com{
2374fd86c2ce3737a82f7a012b7729342972feb1df9dshannon.woods@transgaming.com    // Maximum viewport size must be at least as large as the largest render buffer (or larger).
2375fd86c2ce3737a82f7a012b7729342972feb1df9dshannon.woods@transgaming.com    // In our case return the maximum texture size, which is the maximum render buffer size.
2376fd86c2ce3737a82f7a012b7729342972feb1df9dshannon.woods@transgaming.com    META_ASSERT(D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D11_VIEWPORT_BOUNDS_MAX);
2377fd86c2ce3737a82f7a012b7729342972feb1df9dshannon.woods@transgaming.com    META_ASSERT(D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D10_VIEWPORT_BOUNDS_MAX);
2378fd86c2ce3737a82f7a012b7729342972feb1df9dshannon.woods@transgaming.com
23798ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    switch (mFeatureLevel)
23808ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    {
23818ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_11_0:
2382fd86c2ce3737a82f7a012b7729342972feb1df9dshannon.woods@transgaming.com        return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
23838ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_1:
23848ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com      case D3D_FEATURE_LEVEL_10_0:
2385fd86c2ce3737a82f7a012b7729342972feb1df9dshannon.woods@transgaming.com        return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
23868ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com      default: UNREACHABLE();
23878ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com        return 0;
23888ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com    }
23898ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com}
23908ce2f8f8e9597c045e6cf0c150c9302e7f3466b6shannon.woods@transgaming.com
23911d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comint Renderer11::getMaxTextureWidth() const
23921d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
239325072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    switch (mFeatureLevel)
239425072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    {
239525072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
239625072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com      case D3D_FEATURE_LEVEL_10_1:
239725072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
239825072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com      default: UNREACHABLE();      return 0;
239925072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    }
24001d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
24011d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
24021d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comint Renderer11::getMaxTextureHeight() const
24031d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
240425072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    switch (mFeatureLevel)
240525072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    {
240625072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
240725072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com      case D3D_FEATURE_LEVEL_10_1:
240825072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
240925072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com      default: UNREACHABLE();      return 0;
241025072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    }
24111d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
24121d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
2413c1fdf6baa488d6bf4a16d68c5d83caf2c95563dcshannon.woods%transgaming.com@gtempaccount.comint Renderer11::getMaxTextureDepth() const
2414c1fdf6baa488d6bf4a16d68c5d83caf2c95563dcshannon.woods%transgaming.com@gtempaccount.com{
2415c1fdf6baa488d6bf4a16d68c5d83caf2c95563dcshannon.woods%transgaming.com@gtempaccount.com    switch (mFeatureLevel)
2416c1fdf6baa488d6bf4a16d68c5d83caf2c95563dcshannon.woods%transgaming.com@gtempaccount.com    {
2417c1fdf6baa488d6bf4a16d68c5d83caf2c95563dcshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;   // 2048
2418c1fdf6baa488d6bf4a16d68c5d83caf2c95563dcshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_10_1:
2419c1fdf6baa488d6bf4a16d68c5d83caf2c95563dcshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;   // 2048
2420c1fdf6baa488d6bf4a16d68c5d83caf2c95563dcshannon.woods%transgaming.com@gtempaccount.com      default: UNREACHABLE();      return 0;
2421c1fdf6baa488d6bf4a16d68c5d83caf2c95563dcshannon.woods%transgaming.com@gtempaccount.com    }
2422c1fdf6baa488d6bf4a16d68c5d83caf2c95563dcshannon.woods%transgaming.com@gtempaccount.com}
2423c1fdf6baa488d6bf4a16d68c5d83caf2c95563dcshannon.woods%transgaming.com@gtempaccount.com
2424a98a8111a4b82a2715de171fcf2c7417a9cbfc6fshannon.woods%transgaming.com@gtempaccount.comint Renderer11::getMaxTextureArrayLayers() const
2425a98a8111a4b82a2715de171fcf2c7417a9cbfc6fshannon.woods%transgaming.com@gtempaccount.com{
2426a98a8111a4b82a2715de171fcf2c7417a9cbfc6fshannon.woods%transgaming.com@gtempaccount.com    switch (mFeatureLevel)
2427a98a8111a4b82a2715de171fcf2c7417a9cbfc6fshannon.woods%transgaming.com@gtempaccount.com    {
2428a98a8111a4b82a2715de171fcf2c7417a9cbfc6fshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;   // 2048
2429a98a8111a4b82a2715de171fcf2c7417a9cbfc6fshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_10_1:
2430a98a8111a4b82a2715de171fcf2c7417a9cbfc6fshannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;   // 512
2431a98a8111a4b82a2715de171fcf2c7417a9cbfc6fshannon.woods%transgaming.com@gtempaccount.com      default: UNREACHABLE();      return 0;
2432a98a8111a4b82a2715de171fcf2c7417a9cbfc6fshannon.woods%transgaming.com@gtempaccount.com    }
2433a98a8111a4b82a2715de171fcf2c7417a9cbfc6fshannon.woods%transgaming.com@gtempaccount.com}
2434a98a8111a4b82a2715de171fcf2c7417a9cbfc6fshannon.woods%transgaming.com@gtempaccount.com
24351d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.combool Renderer11::get32BitIndexSupport() const
24361d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
243725072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    switch (mFeatureLevel)
243825072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    {
243925072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com      case D3D_FEATURE_LEVEL_11_0:
244025072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com      case D3D_FEATURE_LEVEL_10_1:
244125072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32;   // true
244225072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com      default: UNREACHABLE();      return false;
244325072f677ccc840ecd35b873fd59046e2e6878fcdaniel@transgaming.com    }
24441d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
24451d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
24461d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comint Renderer11::getMinSwapInterval() const
24471d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
24488c7b1a9d962c90d0c213e80241efad7a31cc1fdadaniel@transgaming.com    return 0;
24491d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
24501d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
24511d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comint Renderer11::getMaxSwapInterval() const
24521d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
24538c7b1a9d962c90d0c213e80241efad7a31cc1fdadaniel@transgaming.com    return 4;
24541d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
24551d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
24561d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.comint Renderer11::getMaxSupportedSamples() const
24571d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com{
2458df2fd572d419751477490fef10db8608e5d73545shannon.woods@transgaming.com    return mMaxSupportedSamples;
24591d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com}
24601d6aff2bc3bdd2c58e051f61cbeb491c30ec852fdaniel@transgaming.com
2461005df41f8900641ed1df60700c8e2eca659a33cbGeoff LangGLsizei Renderer11::getMaxSupportedFormatSamples(GLenum internalFormat) const
24620e120e3daef63029b27860d3b9ad3ae896b78606Geoff Lang{
2463dd4674f2beea11fa31dc41e147c8476cdbbe0910Shannon Woods    DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion());
24640e120e3daef63029b27860d3b9ad3ae896b78606Geoff Lang    MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
24650e120e3daef63029b27860d3b9ad3ae896b78606Geoff Lang    return (iter != mMultisampleSupportMap.end()) ? iter->second.maxSupportedSamples : 0;
24660e120e3daef63029b27860d3b9ad3ae896b78606Geoff Lang}
24670e120e3daef63029b27860d3b9ad3ae896b78606Geoff Lang
2468005df41f8900641ed1df60700c8e2eca659a33cbGeoff LangGLsizei Renderer11::getNumSampleCounts(GLenum internalFormat) const
246952f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods{
247052f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods    unsigned int numCounts = 0;
247152f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods
247252f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods    // D3D11 supports multisampling for signed and unsigned format, but ES 3.0 does not
2473b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang    GLenum componentType = gl::GetComponentType(internalFormat, getCurrentClientVersion());
2474b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang    if (componentType != GL_INT && componentType != GL_UNSIGNED_INT)
247552f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods    {
247652f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods        DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion());
247752f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods        MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
247852f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods
247952f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods        if (iter != mMultisampleSupportMap.end())
248052f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods        {
248152f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods            const MultisampleSupportInfo& info = iter->second;
248252f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods            for (int i = 0; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
248352f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods            {
248452f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods                if (info.qualityLevels[i] > 0)
248552f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods                {
248652f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods                    numCounts++;
248752f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods                }
248852f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods            }
248952f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods        }
249052f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods    }
249152f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods
249252f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods    return numCounts;
249352f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods}
249452f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods
2495005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid Renderer11::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const
249652f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods{
249752f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods    // D3D11 supports multisampling for signed and unsigned format, but ES 3.0 does not
2498b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang    GLenum componentType = gl::GetComponentType(internalFormat, getCurrentClientVersion());
2499b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang    if (componentType == GL_INT || componentType == GL_UNSIGNED_INT)
2500b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang    {
250152f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods        return;
2502b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang    }
250352f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods
250452f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods    DXGI_FORMAT format = gl_d3d11::GetRenderableFormat(internalFormat, getCurrentClientVersion());
250552f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods    MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
250652f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods
250752f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods    if (iter != mMultisampleSupportMap.end())
250852f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods    {
250952f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods        const MultisampleSupportInfo& info = iter->second;
251052f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods        int bufPos = 0;
251152f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods        for (int i = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT - 1; i >= 0 && bufPos < bufSize; i--)
251252f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods        {
251352f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods            if (info.qualityLevels[i] > 0)
251452f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods            {
251552f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods                params[bufPos++] = i + 1;
251652f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods            }
251752f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods        }
251852f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods    }
251952f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods}
252052f1e7ef25a5a93bbabd484278abbf8df77787abShannon Woods
252188fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.comint Renderer11::getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const
252288fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com{
252388fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com    if (requested == 0)
252488fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com    {
252588fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com        return 0;
252688fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com    }
252788fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com
252888fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com    MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
252988fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com    if (iter != mMultisampleSupportMap.end())
253088fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com    {
253188fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com        const MultisampleSupportInfo& info = iter->second;
253288fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com        for (unsigned int i = requested - 1; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
253388fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com        {
253488fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com            if (info.qualityLevels[i] > 0)
253588fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com            {
253688fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com                return i + 1;
253788fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com            }
253888fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com        }
253988fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com    }
254088fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com
254188fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com    return -1;
254288fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com}
254388fbd0feec1c8617a216386d6d20bbe8e68dcee7shannon.woods@transgaming.com
2544b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.comunsigned int Renderer11::getMaxRenderTargets() const
2545b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com{
2546f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    META_ASSERT(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
2547f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com    META_ASSERT(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
2548f30ccc2fd16ac7d6156ff355ec70f422263b043cshannon.woods%transgaming.com@gtempaccount.com
2549b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com    switch (mFeatureLevel)
2550b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com    {
2551b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_11_0:
2552b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com        return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;  // 8
2553b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_10_1:
2554b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com      case D3D_FEATURE_LEVEL_10_0:
2555626d54e8c3eb30a1aab73d3464b669b5ea3e5115Geoff Lang        // Feature level 10.0 and 10.1 cards perform very poorly when the pixel shader
2556626d54e8c3eb30a1aab73d3464b669b5ea3e5115Geoff Lang        // outputs to multiple RTs that are not bound.
2557626d54e8c3eb30a1aab73d3464b669b5ea3e5115Geoff Lang        // TODO: Remove pixel shader outputs for render targets that are not bound.
2558626d54e8c3eb30a1aab73d3464b669b5ea3e5115Geoff Lang        return 1;
2559b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com      default:
2560b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com        UNREACHABLE();
2561b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com        return 1;
2562b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com    }
2563b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com}
2564b290ac1759847f86642ee5a8bd71dd5c5db831f3shannon.woods%transgaming.com@gtempaccount.com
256587705f8292857d1446f0967c43b7fac66a70d9c2daniel@transgaming.combool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source)
2566ad6aee7de9ffae3fa885f5b487a12eea1ae0bac2daniel@transgaming.com{
2567b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com    if (source && dest)
2568b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com    {
2569b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com        TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source->getStorageInstance());
2570b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com        TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest->getStorageInstance());
2571b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com
257276b258f88ebb47cf1022ae6b4392f220a56383d4Nicolas Capens        mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
257342477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
257442477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        dest11->invalidateSwizzleCache();
257542477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
2576b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com        return true;
2577b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com    }
2578b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com
2579ad6aee7de9ffae3fa885f5b487a12eea1ae0bac2daniel@transgaming.com    return false;
2580ad6aee7de9ffae3fa885f5b487a12eea1ae0bac2daniel@transgaming.com}
2581ad6aee7de9ffae3fa885f5b487a12eea1ae0bac2daniel@transgaming.com
258287705f8292857d1446f0967c43b7fac66a70d9c2daniel@transgaming.combool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source)
2583ad6aee7de9ffae3fa885f5b487a12eea1ae0bac2daniel@transgaming.com{
2584b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com    if (source && dest)
2585b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com    {
2586e9cf5e74c74f5cc9fee0b8dd0561f2b606038ba1daniel@transgaming.com        TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source->getStorageInstance());
2587e9cf5e74c74f5cc9fee0b8dd0561f2b606038ba1daniel@transgaming.com        TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest->getStorageInstance());
2588b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com
258976b258f88ebb47cf1022ae6b4392f220a56383d4Nicolas Capens        mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
259042477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
259142477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        dest11->invalidateSwizzleCache();
259242477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
2593b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com        return true;
2594b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com    }
2595b1c208f95b28f3fa618fe3f8ed233d2d40c9417fdaniel@transgaming.com
2596ad6aee7de9ffae3fa885f5b487a12eea1ae0bac2daniel@transgaming.com    return false;
2597ad6aee7de9ffae3fa885f5b487a12eea1ae0bac2daniel@transgaming.com}
2598ad6aee7de9ffae3fa885f5b487a12eea1ae0bac2daniel@transgaming.com
2599414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.combool Renderer11::copyToRenderTarget(TextureStorageInterface3D *dest, TextureStorageInterface3D *source)
2600414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com{
2601414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    if (source && dest)
2602414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    {
2603414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source->getStorageInstance());
2604414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest->getStorageInstance());
2605414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com
260676b258f88ebb47cf1022ae6b4392f220a56383d4Nicolas Capens        mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
260742477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
260842477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        dest11->invalidateSwizzleCache();
260942477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
2610414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        return true;
2611414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    }
2612414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com
2613414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    return false;
2614414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com}
2615414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com
26166c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.combool Renderer11::copyToRenderTarget(TextureStorageInterface2DArray *dest, TextureStorageInterface2DArray *source)
26176c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com{
26186c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    if (source && dest)
26196c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    {
26206c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source->getStorageInstance());
26216c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest->getStorageInstance());
26226c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
262376b258f88ebb47cf1022ae6b4392f220a56383d4Nicolas Capens        mDeviceContext->CopyResource(dest11->getResource(), source11->getResource());
262442477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
262542477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        dest11->invalidateSwizzleCache();
262642477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
26276c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        return true;
26286c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    }
26296c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
26306c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    return false;
26316c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com}
26326c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
2633664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.combool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
263487705f8292857d1446f0967c43b7fac66a70d9c2daniel@transgaming.com                           GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
2635383808834b498363a9c427c85ed635c6476382f0daniel@transgaming.com{
26363c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
26379d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    if (!colorbuffer)
26389d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    {
26399d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com        ERR("Failed to retrieve the color buffer from the frame buffer.");
2640779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
26419d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    }
26429d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
26439d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
26449d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    if (!sourceRenderTarget)
26459d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    {
26469d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com        ERR("Failed to retrieve the render target from the frame buffer.");
2647779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
26489d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    }
26499d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
26509d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
26519d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    if (!source)
26529d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    {
26539d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com        ERR("Failed to retrieve the render target view from the render target.");
2654779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
26559d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    }
26569d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
26579d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance());
26589d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    if (!storage11)
26599d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    {
26609d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com        ERR("Failed to retrieve the texture storage from the destination.");
2661779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
26629d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    }
26639d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
26649d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(level));
26659d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    if (!destRenderTarget)
26669d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    {
26679d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com        ERR("Failed to retrieve the render target from the destination storage.");
2668779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
26699d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    }
26709d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
26719d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
26729d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    if (!dest)
26739d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    {
26749d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com        ERR("Failed to retrieve the render target view from the destination render target.");
2675779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
26769d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    }
26779d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
2678b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
2679b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
26809d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
2681b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
2682b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
26837b61d5cebbe98e9aeb322aaa307e9fcd4c7c682bshannonwoods@chromium.org
2684b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Use nearest filtering because source and destination are the same size for the direct
2685b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // copy
2686125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
2687b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang                                  destFormat, GL_NEAREST);
26889d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
268942477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    storage11->invalidateSwizzleCacheLevel(level);
269042477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
26919d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    return ret;
2692383808834b498363a9c427c85ed635c6476382f0daniel@transgaming.com}
2693383808834b498363a9c427c85ed635c6476382f0daniel@transgaming.com
2694664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.combool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
269587705f8292857d1446f0967c43b7fac66a70d9c2daniel@transgaming.com                           GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
2696383808834b498363a9c427c85ed635c6476382f0daniel@transgaming.com{
26973c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
26989d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    if (!colorbuffer)
26999d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    {
27009d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com        ERR("Failed to retrieve the color buffer from the frame buffer.");
2701779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
27029d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    }
27039d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
27049d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
27059d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    if (!sourceRenderTarget)
27069d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    {
27079d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com        ERR("Failed to retrieve the render target from the frame buffer.");
2708779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
27099d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    }
27109d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
27119d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
27129d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    if (!source)
27139d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    {
27149d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com        ERR("Failed to retrieve the render target view from the render target.");
2715779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
27169d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    }
27179d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
27189d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance());
27199d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    if (!storage11)
27209d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    {
27219d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com        ERR("Failed to retrieve the texture storage from the destination.");
2722779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
27239d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    }
27249d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
2725b13f866ef9bb741ea6fc8f3f594476375531906aNicolas Capens    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetFace(target, level));
27269d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    if (!destRenderTarget)
27279d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    {
27289d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com        ERR("Failed to retrieve the render target from the destination storage.");
2729779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
27309d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    }
27319d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
27329d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
27339d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    if (!dest)
27349d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    {
27359d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com        ERR("Failed to retrieve the render target view from the destination render target.");
2736414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        return gl::error(GL_OUT_OF_MEMORY, false);
2737414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    }
2738414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com
2739b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
2740b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
27417b61d5cebbe98e9aeb322aaa307e9fcd4c7c682bshannonwoods@chromium.org
2742b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
2743b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
2744414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com
2745b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Use nearest filtering because source and destination are the same size for the direct
2746b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // copy
2747125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
2748b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang                                  destFormat, GL_NEAREST);
2749414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com
275042477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    storage11->invalidateSwizzleCacheLevel(level);
275142477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
2752414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    return ret;
2753414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com}
2754414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com
2755414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.combool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
2756414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com                           GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface3D *storage, GLint level)
2757414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com{
27583c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
2759414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    if (!colorbuffer)
2760414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    {
2761414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the color buffer from the frame buffer.");
2762414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        return gl::error(GL_OUT_OF_MEMORY, false);
2763414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    }
2764414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com
2765414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
2766414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    if (!sourceRenderTarget)
2767414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    {
2768414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the render target from the frame buffer.");
2769414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        return gl::error(GL_OUT_OF_MEMORY, false);
2770414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    }
2771414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com
2772414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
2773414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    if (!source)
2774414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    {
2775414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the render target view from the render target.");
2776414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        return gl::error(GL_OUT_OF_MEMORY, false);
2777414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    }
2778414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com
2779414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage->getStorageInstance());
2780414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    if (!storage11)
2781414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    {
2782414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the texture storage from the destination.");
2783414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        return gl::error(GL_OUT_OF_MEMORY, false);
2784414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    }
2785414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com
2786414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetLayer(level, zOffset));
2787414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    if (!destRenderTarget)
2788414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    {
2789414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the render target from the destination storage.");
2790414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        return gl::error(GL_OUT_OF_MEMORY, false);
2791414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    }
2792414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com
2793414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
2794414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    if (!dest)
2795414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com    {
2796414e82afa5dd9ee9eb9b7de0ac2e2191cc8dcadfshannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the render target view from the destination render target.");
2797779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
27989d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    }
27999d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
2800b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
2801b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
28029d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
2803b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
2804b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
28057b61d5cebbe98e9aeb322aaa307e9fcd4c7c682bshannonwoods@chromium.org
2806b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Use nearest filtering because source and destination are the same size for the direct
2807b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // copy
2808125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
2809b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang                                  destFormat, GL_NEAREST);
28109d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
281142477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    storage11->invalidateSwizzleCacheLevel(level);
281242477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
28139d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com    return ret;
28149d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com}
28159d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com
28166c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.combool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
28176c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com                           GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level)
28186c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com{
28193c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
28206c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    if (!colorbuffer)
28216c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    {
28226c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the color buffer from the frame buffer.");
28236c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        return gl::error(GL_OUT_OF_MEMORY, false);
28246c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    }
28256c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
28266c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
28276c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    if (!sourceRenderTarget)
28286c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    {
28296c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the render target from the frame buffer.");
28306c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        return gl::error(GL_OUT_OF_MEMORY, false);
28316c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    }
28326c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
28336c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
28346c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    if (!source)
28356c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    {
28366c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the render target view from the render target.");
28376c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        return gl::error(GL_OUT_OF_MEMORY, false);
28386c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    }
28396c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
28406c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage->getStorageInstance());
28416c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    if (!storage11)
28426c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    {
2843ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(source);
28446c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the texture storage from the destination.");
28456c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        return gl::error(GL_OUT_OF_MEMORY, false);
28466c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    }
28476c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
28486c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTargetLayer(level, zOffset));
28496c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    if (!destRenderTarget)
28506c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    {
2851ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(source);
28526c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the render target from the destination storage.");
28536c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        return gl::error(GL_OUT_OF_MEMORY, false);
28546c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    }
28556c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
28566c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
28576c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    if (!dest)
28586c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    {
28596c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the render target view from the destination render target.");
28606c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        return gl::error(GL_OUT_OF_MEMORY, false);
28616c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    }
28626c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
2863b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
2864b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
28657b61d5cebbe98e9aeb322aaa307e9fcd4c7c682bshannonwoods@chromium.org
2866b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
2867b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
28686c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
2869b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // Use nearest filtering because source and destination are the same size for the direct
2870b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang    // copy
2871125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL,
2872b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang                                  destFormat, GL_NEAREST);
28736c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
287442477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    storage11->invalidateSwizzleCacheLevel(level);
287542477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
28766c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com    return ret;
28776c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com}
28786c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
2879ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.comvoid Renderer11::unapplyRenderTargets()
2880ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com{
2881ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com    setOneTimeRenderTarget(NULL);
2882ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com}
2883ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com
2884ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.comvoid Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView)
2885ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com{
2886ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com    ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
2887ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com
2888ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com    rtvArray[0] = renderTargetView;
2889ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com
2890ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com    mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), rtvArray, NULL);
2891ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com
2892ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com    // Do not preserve the serial for this one-time-use render target
2893ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com    for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
2894ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com    {
2895ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com        mAppliedRenderTargetSerials[rtIndex] = 0;
2896ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com    }
2897ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com}
2898ba2744fdf21d252c3d78efde67d64eb66b642453shannon.woods%transgaming.com@gtempaccount.com
2899f2423659230818b46346496f5212fc3d1f0b537fdaniel@transgaming.comRenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
2900f2423659230818b46346496f5212fc3d1f0b537fdaniel@transgaming.com{
2901183408d0c4fdaa702329c5a386e09129aa8b2bb2shannon.woods@transgaming.com    SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
2902b6b27bc4179f0cab0c64c599d19ce2f4f2623d98daniel@transgaming.com    RenderTarget11 *renderTarget = NULL;
29038c6d9df2f486d4245bc44be08530d432bce08593shannon.woods@transgaming.com
2904b6b27bc4179f0cab0c64c599d19ce2f4f2623d98daniel@transgaming.com    if (depth)
2905b6b27bc4179f0cab0c64c599d19ce2f4f2623d98daniel@transgaming.com    {
29068c6d9df2f486d4245bc44be08530d432bce08593shannon.woods@transgaming.com        // Note: depth stencil may be NULL for 0 sized surfaces
29077e23285f51e48e8f3d75c99a1451023543fb4c66shannon.woods@transgaming.com        renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(),
290888f9cbf254dbc9ee0d87c84155cbcd3b2ca4f853Geoff Lang                                          swapChain11->getDepthStencilTexture(),
290988f9cbf254dbc9ee0d87c84155cbcd3b2ca4f853Geoff Lang                                          swapChain11->getDepthStencilShaderResource(),
29107faf3ec71a8b7cdf81ee9336bf5e1aae133a18f0shannonwoods@chromium.org                                          swapChain11->getWidth(), swapChain11->getHeight(), 1);
2911b6b27bc4179f0cab0c64c599d19ce2f4f2623d98daniel@transgaming.com    }
2912b6b27bc4179f0cab0c64c599d19ce2f4f2623d98daniel@transgaming.com    else
2913b6b27bc4179f0cab0c64c599d19ce2f4f2623d98daniel@transgaming.com    {
29148c6d9df2f486d4245bc44be08530d432bce08593shannon.woods@transgaming.com        // Note: render target may be NULL for 0 sized surfaces
2915183408d0c4fdaa702329c5a386e09129aa8b2bb2shannon.woods@transgaming.com        renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(),
29167e23285f51e48e8f3d75c99a1451023543fb4c66shannon.woods@transgaming.com                                          swapChain11->getOffscreenTexture(),
2917183408d0c4fdaa702329c5a386e09129aa8b2bb2shannon.woods@transgaming.com                                          swapChain11->getRenderTargetShaderResource(),
29187faf3ec71a8b7cdf81ee9336bf5e1aae133a18f0shannonwoods@chromium.org                                          swapChain11->getWidth(), swapChain11->getHeight(), 1);
2919b6b27bc4179f0cab0c64c599d19ce2f4f2623d98daniel@transgaming.com    }
2920b6b27bc4179f0cab0c64c599d19ce2f4f2623d98daniel@transgaming.com    return renderTarget;
2921f2423659230818b46346496f5212fc3d1f0b537fdaniel@transgaming.com}
2922f2423659230818b46346496f5212fc3d1f0b537fdaniel@transgaming.com
2923a2d97f13f648c978e942ce55df7a940d9944ef2eGeoff LangRenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples)
2924f2423659230818b46346496f5212fc3d1f0b537fdaniel@transgaming.com{
2925a2d97f13f648c978e942ce55df7a940d9944ef2eGeoff Lang    RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples);
2926c9a501dc27ed761a701c5095ee2e4f8b281e8c39daniel@transgaming.com    return renderTarget;
2927f2423659230818b46346496f5212fc3d1f0b537fdaniel@transgaming.com}
2928f2423659230818b46346496f5212fc3d1f0b537fdaniel@transgaming.com
292948dcae7b217420a7387c84a76651989e6f5f3576Geoff LangShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type,
293048dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                                             const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
293148dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                                             bool separatedOutputBuffers)
29325531890fd23a8747eda7d11acf23df8117d6d944daniel@transgaming.com{
2933a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com    ShaderExecutable11 *executable = NULL;
293448dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    HRESULT result;
2935a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com
2936a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com    switch (type)
2937a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com    {
293869ff7766ef5fb53d02dc1ff37066bead3a570abdshannon.woods@transgaming.com      case rx::SHADER_VERTEX:
2939a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com        {
294048dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            ID3D11VertexShader *vertexShader = NULL;
294148dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            ID3D11GeometryShader *streamOutShader = NULL;
294248dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang
294348dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader);
2944a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com            ASSERT(SUCCEEDED(result));
2945a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com
294648dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            if (transformFeedbackVaryings.size() > 0)
2947a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com            {
294848dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                std::vector<D3D11_SO_DECLARATION_ENTRY> soDeclaration;
294948dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                for (size_t i = 0; i < transformFeedbackVaryings.size(); i++)
295048dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                {
295148dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                    const gl::LinkedVarying &varying = transformFeedbackVaryings[i];
2952cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang                    for (size_t j = 0; j < varying.semanticIndexCount; j++)
295348dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                    {
295448dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                        D3D11_SO_DECLARATION_ENTRY entry = { 0 };
295548dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                        entry.Stream = 0;
2956cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang                        entry.SemanticName = varying.semanticName.c_str();
2957cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang                        entry.SemanticIndex = varying.semanticIndex + j;
295848dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                        entry.StartComponent = 0;
295948dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                        entry.ComponentCount = gl::VariableRowCount(type);
296048dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                        entry.OutputSlot = (separatedOutputBuffers ? i : 0);
296148dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                        soDeclaration.push_back(entry);
296248dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                    }
296348dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                }
296448dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang
296548dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                result = mDevice->CreateGeometryShaderWithStreamOutput(function, length, soDeclaration.data(), soDeclaration.size(),
296648dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                                                                       NULL, 0, 0, NULL, &streamOutShader);
296748dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                ASSERT(SUCCEEDED(result));
296848dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            }
296948dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang
297048dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            if (vertexShader)
297148dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            {
297248dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                executable = new ShaderExecutable11(function, length, vertexShader, streamOutShader);
2973a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com            }
2974a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com        }
2975a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com        break;
297669ff7766ef5fb53d02dc1ff37066bead3a570abdshannon.woods@transgaming.com      case rx::SHADER_PIXEL:
2977a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com        {
297848dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            ID3D11PixelShader *pixelShader = NULL;
297948dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang
298048dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader);
2981a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com            ASSERT(SUCCEEDED(result));
2982a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com
298348dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            if (pixelShader)
2984a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com            {
298548dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                executable = new ShaderExecutable11(function, length, pixelShader);
2986a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com            }
2987a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com        }
2988a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com        break;
29893e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com      case rx::SHADER_GEOMETRY:
29903e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com        {
299148dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            ID3D11GeometryShader *geometryShader = NULL;
299248dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang
299348dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader);
29943e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com            ASSERT(SUCCEEDED(result));
29953e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com
299648dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang            if (geometryShader)
29973e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com            {
299848dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                executable = new ShaderExecutable11(function, length, geometryShader);
29993e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com            }
30003e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com        }
30013e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com        break;
3002a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com      default:
3003a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com        UNREACHABLE();
3004a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com        break;
3005a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com    }
3006a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com
3007a2f9fbe3903671b6c427f7dc11ac0bec94a9538cdaniel@transgaming.com    return executable;
30085531890fd23a8747eda7d11acf23df8117d6d944daniel@transgaming.com}
30095531890fd23a8747eda7d11acf23df8117d6d944daniel@transgaming.com
301048dcae7b217420a7387c84a76651989e6f5f3576Geoff LangShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type,
301148dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                                                  const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
301248dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                                                  bool separatedOutputBuffers, D3DWorkaroundType workaround)
3013a9c7142435f100d43684a0efe8894cbe42ee8fccdaniel@transgaming.com{
30146e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang    const char *profileType = NULL;
3015071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com    switch (type)
3016071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com    {
301769ff7766ef5fb53d02dc1ff37066bead3a570abdshannon.woods@transgaming.com      case rx::SHADER_VERTEX:
30186e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang        profileType = "vs";
3019071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com        break;
302069ff7766ef5fb53d02dc1ff37066bead3a570abdshannon.woods@transgaming.com      case rx::SHADER_PIXEL:
30216e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang        profileType = "ps";
3022071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com        break;
30233e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com      case rx::SHADER_GEOMETRY:
30246e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang        profileType = "gs";
30253e773bb4f1a2202d02a546d18ca6e8d9d2440006shannon.woods@transgaming.com        break;
3026071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com      default:
3027071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com        UNREACHABLE();
3028071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com        return NULL;
3029071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com    }
3030071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com
30316e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang    const char *profileVersion = NULL;
30326e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang    switch (mFeatureLevel)
30336e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang    {
30346e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang      case D3D_FEATURE_LEVEL_11_0:
30356e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang        profileVersion = "5_0";
30366e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang        break;
30376e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang      case D3D_FEATURE_LEVEL_10_1:
30386e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang        profileVersion = "4_1";
30396e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang        break;
30406e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang      case D3D_FEATURE_LEVEL_10_0:
30416e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang        profileVersion = "4_0";
30426e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang        break;
30436e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang      default:
30446e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang        UNREACHABLE();
30456e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang        return NULL;
30466e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang    }
30476e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang
30486e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang    char profile[32];
30496e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang    snprintf(profile, ArraySize(profile), "%s_%s", profileType, profileVersion);
30506e05c2724d6939c40b858d78de0a0b3f08aeeac8Geoff Lang
305193faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL0;
305293faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens
305393faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    if (gl::perfActive())
305493faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    {
305593faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens#ifndef NDEBUG
305693faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens        flags = D3DCOMPILE_SKIP_OPTIMIZATION;
305793faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens#endif
305893faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens
305993faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens        flags |= D3DCOMPILE_DEBUG;
306093faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens
306193faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens        std::string sourcePath = getTempPath();
306293faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens        std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL);
306393faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens        writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
306493faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    }
306593faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens
306693faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
306793faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    // Try the default flags first and if compilation fails, try some alternatives.
306893faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    const UINT extraFlags[] =
306993faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    {
30701408bae66650f2ceb17801ba9780a853f794580eNicolas Capens        flags,
30712c27db6f38022303a1efa7a2ad8d1e78c958e2aaNicolas Capens        flags | D3DCOMPILE_SKIP_VALIDATION,
30722c27db6f38022303a1efa7a2ad8d1e78c958e2aaNicolas Capens        flags | D3DCOMPILE_SKIP_OPTIMIZATION
307393faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    };
307493faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens
307593faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    const static char *extraFlagNames[] =
307693faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    {
30771408bae66650f2ceb17801ba9780a853f794580eNicolas Capens        "default",
30782c27db6f38022303a1efa7a2ad8d1e78c958e2aaNicolas Capens        "skip validation",
30792c27db6f38022303a1efa7a2ad8d1e78c958e2aaNicolas Capens        "skip optimization"
308093faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    };
308193faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens
308293faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    int attempts = ArraySize(extraFlags);
308393faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens
308493faad9f65ebda46102f628dadb92b12126ea652Nicolas Capens    ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts);
3085071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com    if (!binary)
3086ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    {
3087071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com        return NULL;
3088ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    }
3089071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com
309048dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type,
309148dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang                                                  transformFeedbackVaryings, separatedOutputBuffers);
3092ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(binary);
3093071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com
3094071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com    return executable;
3095071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com}
3096071ee6a691119083d7479d5e01c6cd1a51dcfabcdaniel@transgaming.com
30978ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madillrx::UniformStorage *Renderer11::createUniformStorage(size_t storageSize)
30988ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill{
30998ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill    return new UniformStorage11(this, storageSize);
31008ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill}
31018ff21aeaabebd0877c1cc48fdac718509f23617aJamie Madill
31023f255b48a70b8f720d5da7cf2046eb81ba6606c2daniel@transgaming.comVertexBuffer *Renderer11::createVertexBuffer()
31033f255b48a70b8f720d5da7cf2046eb81ba6606c2daniel@transgaming.com{
31042c4d070c77f2ce54eeebf7e967b99986a7f18ef0daniel@transgaming.com    return new VertexBuffer11(this);
31053f255b48a70b8f720d5da7cf2046eb81ba6606c2daniel@transgaming.com}
31063f255b48a70b8f720d5da7cf2046eb81ba6606c2daniel@transgaming.com
31070b6d7741f627082bc197034e43da47e975909238daniel@transgaming.comIndexBuffer *Renderer11::createIndexBuffer()
31080b6d7741f627082bc197034e43da47e975909238daniel@transgaming.com{
310911c2af555ad90d9079b2a55398253f165616712cdaniel@transgaming.com    return new IndexBuffer11(this);
3110cfe787e70c714a2163e67985de34d219aea7f2a7shannon.woods@transgaming.com}
3111cfe787e70c714a2163e67985de34d219aea7f2a7shannon.woods@transgaming.com
31124e52b6356288e7d6aa46ae77e4b2ada8aee4e3c3shannon.woods@transgaming.comBufferStorage *Renderer11::createBufferStorage()
31134e52b6356288e7d6aa46ae77e4b2ada8aee4e3c3shannon.woods@transgaming.com{
31144e52b6356288e7d6aa46ae77e4b2ada8aee4e3c3shannon.woods@transgaming.com    return new BufferStorage11(this);
31154e52b6356288e7d6aa46ae77e4b2ada8aee4e3c3shannon.woods@transgaming.com}
31164e52b6356288e7d6aa46ae77e4b2ada8aee4e3c3shannon.woods@transgaming.com
3117cfe787e70c714a2163e67985de34d219aea7f2a7shannon.woods@transgaming.comQueryImpl *Renderer11::createQuery(GLenum type)
3118cfe787e70c714a2163e67985de34d219aea7f2a7shannon.woods@transgaming.com{
31198b7606aad42b7eb5a183b502902106f9ba6f7ac4shannon.woods@transgaming.com    return new Query11(this, type);
3120cfe787e70c714a2163e67985de34d219aea7f2a7shannon.woods@transgaming.com}
3121cfe787e70c714a2163e67985de34d219aea7f2a7shannon.woods@transgaming.com
3122cfe787e70c714a2163e67985de34d219aea7f2a7shannon.woods@transgaming.comFenceImpl *Renderer11::createFence()
3123cfe787e70c714a2163e67985de34d219aea7f2a7shannon.woods@transgaming.com{
3124be58aa08c2867e3483afb6313c5c06cf35c724d4shannon.woods@transgaming.com    return new Fence11(this);
31250b6d7741f627082bc197034e43da47e975909238daniel@transgaming.com}
31260b6d7741f627082bc197034e43da47e975909238daniel@transgaming.com
3127005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langbool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
31280e0510fd08426f39f104c5dc937c9d7f4469db95Jamie Madill{
31294461f097210919c9c99e0bda049f465c36301a2dJamie Madill    int clientVersion = getCurrentClientVersion();
31304461f097210919c9c99e0bda049f465c36301a2dJamie Madill
31314461f097210919c9c99e0bda049f465c36301a2dJamie Madill    // We only support buffer to texture copies in ES3
31324461f097210919c9c99e0bda049f465c36301a2dJamie Madill    if (clientVersion <= 2)
31334461f097210919c9c99e0bda049f465c36301a2dJamie Madill    {
31344461f097210919c9c99e0bda049f465c36301a2dJamie Madill        return false;
31354461f097210919c9c99e0bda049f465c36301a2dJamie Madill    }
31364461f097210919c9c99e0bda049f465c36301a2dJamie Madill
31374461f097210919c9c99e0bda049f465c36301a2dJamie Madill    // sRGB formats do not work with D3D11 buffer SRVs
31384461f097210919c9c99e0bda049f465c36301a2dJamie Madill    if (gl::GetColorEncoding(internalFormat, clientVersion) == GL_SRGB)
31394461f097210919c9c99e0bda049f465c36301a2dJamie Madill    {
31404461f097210919c9c99e0bda049f465c36301a2dJamie Madill        return false;
31414461f097210919c9c99e0bda049f465c36301a2dJamie Madill    }
31424461f097210919c9c99e0bda049f465c36301a2dJamie Madill
31434461f097210919c9c99e0bda049f465c36301a2dJamie Madill    // We cannot support direct copies to non-color-renderable formats
31444461f097210919c9c99e0bda049f465c36301a2dJamie Madill    if (!gl::IsColorRenderingSupported(internalFormat, this))
31454461f097210919c9c99e0bda049f465c36301a2dJamie Madill    {
31464461f097210919c9c99e0bda049f465c36301a2dJamie Madill        return false;
31474461f097210919c9c99e0bda049f465c36301a2dJamie Madill    }
31484461f097210919c9c99e0bda049f465c36301a2dJamie Madill
31494461f097210919c9c99e0bda049f465c36301a2dJamie Madill    // We skip all 3-channel formats since sometimes format support is missing
31504461f097210919c9c99e0bda049f465c36301a2dJamie Madill    if (gl::GetComponentCount(internalFormat, clientVersion) == 3)
31514461f097210919c9c99e0bda049f465c36301a2dJamie Madill    {
31524461f097210919c9c99e0bda049f465c36301a2dJamie Madill        return false;
31534461f097210919c9c99e0bda049f465c36301a2dJamie Madill    }
31544461f097210919c9c99e0bda049f465c36301a2dJamie Madill
31554461f097210919c9c99e0bda049f465c36301a2dJamie Madill    // We don't support formats which we can't represent without conversion
31564461f097210919c9c99e0bda049f465c36301a2dJamie Madill    if (getNativeTextureFormat(internalFormat) != internalFormat)
31574461f097210919c9c99e0bda049f465c36301a2dJamie Madill    {
31584461f097210919c9c99e0bda049f465c36301a2dJamie Madill        return false;
31594461f097210919c9c99e0bda049f465c36301a2dJamie Madill    }
31604461f097210919c9c99e0bda049f465c36301a2dJamie Madill
31614461f097210919c9c99e0bda049f465c36301a2dJamie Madill    return true;
31620e0510fd08426f39f104c5dc937c9d7f4469db95Jamie Madill}
31630e0510fd08426f39f104c5dc937c9d7f4469db95Jamie Madill
3164a21eea36fbb03d7d680ca7f472fcf96b1bbc1f63Jamie Madillbool Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
3165a21eea36fbb03d7d680ca7f472fcf96b1bbc1f63Jamie Madill                                         GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
3166a21eea36fbb03d7d680ca7f472fcf96b1bbc1f63Jamie Madill{
31670e0510fd08426f39f104c5dc937c9d7f4469db95Jamie Madill    ASSERT(supportsFastCopyBufferToTexture(destinationFormat));
3168a21eea36fbb03d7d680ca7f472fcf96b1bbc1f63Jamie Madill    return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea);
3169a21eea36fbb03d7d680ca7f472fcf96b1bbc1f63Jamie Madill}
3170a21eea36fbb03d7d680ca7f472fcf96b1bbc1f63Jamie Madill
31713c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madillbool Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource)
31726c87217467896d150743db19e2ed664ceec56785daniel@transgaming.com{
317300e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com    ASSERT(colorbuffer != NULL);
317400e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com
317500e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com    RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
317600e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com    if (renderTarget)
3177ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    {
317800e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com        *subresourceIndex = renderTarget->getSubresourceIndex();
317900e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com
318000e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com        ID3D11RenderTargetView *colorBufferRTV = renderTarget->getRenderTargetView();
318100e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com        if (colorBufferRTV)
3182ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        {
318300e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com            ID3D11Resource *textureResource = NULL;
318400e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com            colorBufferRTV->GetResource(&textureResource);
31852eb7ab71135b777e6d040284c99132e9fbc696dadaniel@transgaming.com
318600e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com            if (textureResource)
3187ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com            {
31888e32884af9c0171974821c130f1c4b3e9cd59987Geoff Lang                HRESULT result = textureResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)resource);
3189ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang                SafeRelease(textureResource);
3190ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
319100e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com                if (SUCCEEDED(result))
3192ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com                {
319300e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com                    return true;
319400e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com                }
319500e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com                else
319600e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com                {
319700e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com                    ERR("Failed to extract the ID3D11Texture2D from the render target resource, "
319800e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com                        "HRESULT: 0x%X.", result);
3199ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com                }
3200ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com            }
3201ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        }
3202ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    }
3203ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
3204fdeacb8176e34112da113b3bb7e97692fb557419shannon.woods@transgaming.com    return false;
3205fdeacb8176e34112da113b3bb7e97692fb557419shannon.woods@transgaming.com}
3206fdeacb8176e34112da113b3bb7e97692fb557419shannon.woods@transgaming.com
3207ea4a0c6671ab0b079ed5e0313699742d1c6a9bd1shannon.woods@transgaming.combool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
3208125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                          const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter)
3209fdeacb8176e34112da113b3bb7e97692fb557419shannon.woods@transgaming.com{
32101d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com    if (blitRenderTarget)
32111e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    {
32123c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        gl::FramebufferAttachment *readBuffer = readTarget->getReadColorbuffer();
32131d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com
32141d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        if (!readBuffer)
32151d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        {
32161d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com            ERR("Failed to retrieve the read buffer from the read framebuffer.");
32171d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com            return gl::error(GL_OUT_OF_MEMORY, false);
32181d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        }
32191d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com
32201d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        RenderTarget *readRenderTarget = readBuffer->getRenderTarget();
32211d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com
3222f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com        for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
32231d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        {
3224f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com            if (drawTarget->isEnabledColorAttachment(colorAttachment))
3225f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com            {
32263c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill                gl::FramebufferAttachment *drawBuffer = drawTarget->getColorbuffer(colorAttachment);
3227f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com
3228f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com                if (!drawBuffer)
3229f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com                {
3230f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com                    ERR("Failed to retrieve the draw buffer from the draw framebuffer.");
3231f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com                    return gl::error(GL_OUT_OF_MEMORY, false);
3232f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com                }
3233f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com
3234f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com                RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget();
3235f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com
3236125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor,
3237685806d62991e99b9cde6e639a6a4b9263f28e70Geoff Lang                                          blitRenderTarget, false, false))
3238f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com                {
3239f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com                    return false;
3240f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com                }
3241f6863e0af2d81ed56371c6c7ec6468e685e31289shannon.woods%transgaming.com@gtempaccount.com            }
32421d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        }
32431e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    }
32441e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com
3245685806d62991e99b9cde6e639a6a4b9263f28e70Geoff Lang    if (blitDepth || blitStencil)
32461e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    {
32473c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        gl::FramebufferAttachment *readBuffer = readTarget->getDepthOrStencilbuffer();
32483c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer();
32491d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com
32501d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        if (!readBuffer)
32511d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        {
32521d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com            ERR("Failed to retrieve the read depth-stencil buffer from the read framebuffer.");
32531d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com            return gl::error(GL_OUT_OF_MEMORY, false);
32541d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        }
32551d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com
32561d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        if (!drawBuffer)
32571d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        {
32581d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com            ERR("Failed to retrieve the draw depth-stencil buffer from the draw framebuffer.");
32591d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com            return gl::error(GL_OUT_OF_MEMORY, false);
32601d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        }
32611d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com
32621d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        RenderTarget *readRenderTarget = readBuffer->getDepthStencil();
32631d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil();
32641d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com
3265125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor,
3266685806d62991e99b9cde6e639a6a4b9263f28e70Geoff Lang                                  false, blitDepth, blitStencil))
32671d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        {
32681d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com            return false;
32691d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        }
32701e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    }
32711e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com
327242477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    invalidateFramebufferSwizzles(drawTarget);
327342477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
32741e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    return true;
3275fdeacb8176e34112da113b3bb7e97692fb557419shannon.woods@transgaming.com}
3276fdeacb8176e34112da113b3bb7e97692fb557419shannon.woods@transgaming.com
3277eb9baabb73632231c8c1a26dc4d3647e17262ba7Jamie Madillvoid Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
3278eb9baabb73632231c8c1a26dc4d3647e17262ba7Jamie Madill                            GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void* pixels)
3279fdeacb8176e34112da113b3bb7e97692fb557419shannon.woods@transgaming.com{
3280fdeacb8176e34112da113b3bb7e97692fb557419shannon.woods@transgaming.com    ID3D11Texture2D *colorBufferTexture = NULL;
3281fdeacb8176e34112da113b3bb7e97692fb557419shannon.woods@transgaming.com    unsigned int subresourceIndex = 0;
3282fdeacb8176e34112da113b3bb7e97692fb557419shannon.woods@transgaming.com
32833c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
328400e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com
328500e3f0c7cdda2b28a7aa888cf73146908b8a0848shannon.woods%transgaming.com@gtempaccount.com    if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
3286ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    {
3287ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        gl::Rectangle area;
3288ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        area.x = x;
3289ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        area.y = y;
3290ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        area.width = width;
3291ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        area.height = height;
3292ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
32931ef6fe7748b5d5a440a53d985d6c98ee763cbc56Jamie Madill        if (pack.pixelBuffer.get() != NULL)
32941ef6fe7748b5d5a440a53d985d6c98ee763cbc56Jamie Madill        {
32951ef6fe7748b5d5a440a53d985d6c98ee763cbc56Jamie Madill            rx::BufferStorage11 *packBufferStorage = BufferStorage11::makeBufferStorage11(pack.pixelBuffer.get()->getStorage());
32961ef6fe7748b5d5a440a53d985d6c98ee763cbc56Jamie Madill            PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
32971ef6fe7748b5d5a440a53d985d6c98ee763cbc56Jamie Madill            packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
32981ef6fe7748b5d5a440a53d985d6c98ee763cbc56Jamie Madill        }
32991ef6fe7748b5d5a440a53d985d6c98ee763cbc56Jamie Madill        else
33001ef6fe7748b5d5a440a53d985d6c98ee763cbc56Jamie Madill        {
33011ef6fe7748b5d5a440a53d985d6c98ee763cbc56Jamie Madill            readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
33021ef6fe7748b5d5a440a53d985d6c98ee763cbc56Jamie Madill        }
3303ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
3304ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeRelease(colorBufferTexture);
3305ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    }
33066c87217467896d150743db19e2ed664ceec56785daniel@transgaming.com}
33076c87217467896d150743db19e2ed664ceec56785daniel@transgaming.com
3308244e1838a3d475c26e6bc1830aab5e87f8bf8c48daniel@transgaming.comImage *Renderer11::createImage()
3309244e1838a3d475c26e6bc1830aab5e87f8bf8c48daniel@transgaming.com{
3310a8aac672c49a9e9b0a191ebe7bf2b7cfa649ea22daniel@transgaming.com    return new Image11();
3311244e1838a3d475c26e6bc1830aab5e87f8bf8c48daniel@transgaming.com}
3312244e1838a3d475c26e6bc1830aab5e87f8bf8c48daniel@transgaming.com
3313f721fdbdaa5c675e60115e8f0203956f848c1fc1daniel@transgaming.comvoid Renderer11::generateMipmap(Image *dest, Image *src)
3314f721fdbdaa5c675e60115e8f0203956f848c1fc1daniel@transgaming.com{
33152b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com    Image11 *dest11 = Image11::makeImage11(dest);
33162b132f42050d9005cacac5796a9431d0f40cccc1shannon.woods@transgaming.com    Image11 *src11 = Image11::makeImage11(src);
3317d6cb2443a9805314d214dd448835ea6a58fc8c7dJamie Madill    Image11::generateMipmap(getCurrentClientVersion(), dest11, src11);
3318f721fdbdaa5c675e60115e8f0203956f848c1fc1daniel@transgaming.com}
3319f721fdbdaa5c675e60115e8f0203956f848c1fc1daniel@transgaming.com
3320413d27110d15e3f218ab8b1db01d08cdc036edb6daniel@transgaming.comTextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain)
3321413d27110d15e3f218ab8b1db01d08cdc036edb6daniel@transgaming.com{
332236670db654ab1e943cce86ceb0c8e9aa6de381a0daniel@transgaming.com    SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
332336670db654ab1e943cce86ceb0c8e9aa6de381a0daniel@transgaming.com    return new TextureStorage11_2D(this, swapChain11);
3324413d27110d15e3f218ab8b1db01d08cdc036edb6daniel@transgaming.com}
3325413d27110d15e3f218ab8b1db01d08cdc036edb6daniel@transgaming.com
3326bf712d0a32847868913a3521b44912a5c29f08b8Nicolas CapensTextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
3327413d27110d15e3f218ab8b1db01d08cdc036edb6daniel@transgaming.com{
3328bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return new TextureStorage11_2D(this, internalformat, renderTarget, width, height, levels);
3329413d27110d15e3f218ab8b1db01d08cdc036edb6daniel@transgaming.com}
3330413d27110d15e3f218ab8b1db01d08cdc036edb6daniel@transgaming.com
3331bf712d0a32847868913a3521b44912a5c29f08b8Nicolas CapensTextureStorage *Renderer11::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels)
3332413d27110d15e3f218ab8b1db01d08cdc036edb6daniel@transgaming.com{
3333bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return new TextureStorage11_Cube(this, internalformat, renderTarget, size, levels);
3334413d27110d15e3f218ab8b1db01d08cdc036edb6daniel@transgaming.com}
3335413d27110d15e3f218ab8b1db01d08cdc036edb6daniel@transgaming.com
3336bf712d0a32847868913a3521b44912a5c29f08b8Nicolas CapensTextureStorage *Renderer11::createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels)
33372058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com{
3338bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return new TextureStorage11_3D(this, internalformat, renderTarget, width, height, depth, levels);
33392058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com}
33402058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
3341bf712d0a32847868913a3521b44912a5c29f08b8Nicolas CapensTextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels)
33426c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com{
3343bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels);
33446c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com}
33456c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com
3346eb9baabb73632231c8c1a26dc4d3647e17262ba7Jamie Madillvoid Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
3347eb9baabb73632231c8c1a26dc4d3647e17262ba7Jamie Madill                                 GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, void *pixels)
3348ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com{
33491eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    ASSERT(area.width >= 0);
33501eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    ASSERT(area.height >= 0);
33511eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill
3352ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    D3D11_TEXTURE2D_DESC textureDesc;
3353ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    texture->GetDesc(&textureDesc);
3354ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
33551eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    // Clamp read region to the defined texture boundaries, preventing out of bounds reads
33561eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    // and reads of uninitialized data.
33571eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    gl::Rectangle safeArea;
33581eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    safeArea.x      = gl::clamp(area.x, 0, static_cast<int>(textureDesc.Width));
33591eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    safeArea.y      = gl::clamp(area.y, 0, static_cast<int>(textureDesc.Height));
33601eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    safeArea.width  = gl::clamp(area.width + std::min(area.x, 0), 0,
33611eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill                                static_cast<int>(textureDesc.Width) - safeArea.x);
33621eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    safeArea.height = gl::clamp(area.height + std::min(area.y, 0), 0,
33631eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill                                static_cast<int>(textureDesc.Height) - safeArea.y);
33641eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill
33651eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    ASSERT(safeArea.x >= 0 && safeArea.y >= 0);
33661eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    ASSERT(safeArea.x + safeArea.width  <= static_cast<int>(textureDesc.Width));
33671eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    ASSERT(safeArea.y + safeArea.height <= static_cast<int>(textureDesc.Height));
33681eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill
33691eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    if (safeArea.width == 0 || safeArea.height == 0)
33701eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    {
33711eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill        // no work to do
33721eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill        return;
33731eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    }
33741eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill
3375ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    D3D11_TEXTURE2D_DESC stagingDesc;
33761eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    stagingDesc.Width = safeArea.width;
33771eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    stagingDesc.Height = safeArea.height;
3378ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    stagingDesc.MipLevels = 1;
3379ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    stagingDesc.ArraySize = 1;
3380ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    stagingDesc.Format = textureDesc.Format;
3381ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    stagingDesc.SampleDesc.Count = 1;
3382ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    stagingDesc.SampleDesc.Quality = 0;
3383ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    stagingDesc.Usage = D3D11_USAGE_STAGING;
3384ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    stagingDesc.BindFlags = 0;
3385ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
3386ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    stagingDesc.MiscFlags = 0;
3387ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
3388ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    ID3D11Texture2D* stagingTex = NULL;
3389ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex);
3390ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    if (FAILED(result))
3391ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    {
3392ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        ERR("Failed to create staging texture for readPixels, HRESULT: 0x%X.", result);
3393ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        return;
3394ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    }
3395ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
3396ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    ID3D11Texture2D* srcTex = NULL;
3397ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    if (textureDesc.SampleDesc.Count > 1)
3398ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    {
3399ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        D3D11_TEXTURE2D_DESC resolveDesc;
3400ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        resolveDesc.Width = textureDesc.Width;
3401ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        resolveDesc.Height = textureDesc.Height;
3402ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        resolveDesc.MipLevels = 1;
3403ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        resolveDesc.ArraySize = 1;
3404ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        resolveDesc.Format = textureDesc.Format;
3405ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        resolveDesc.SampleDesc.Count = 1;
3406ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        resolveDesc.SampleDesc.Quality = 0;
3407ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        resolveDesc.Usage = D3D11_USAGE_DEFAULT;
3408ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        resolveDesc.BindFlags = 0;
3409ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        resolveDesc.CPUAccessFlags = 0;
3410ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        resolveDesc.MiscFlags = 0;
3411ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
3412ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex);
3413ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        if (FAILED(result))
3414ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        {
3415ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com            ERR("Failed to create resolve texture for readPixels, HRESULT: 0x%X.", result);
3416ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang            SafeRelease(stagingTex);
3417ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com            return;
3418ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        }
3419ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
3420ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format);
3421ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        subResource = 0;
3422ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    }
3423ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    else
3424ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    {
3425ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        srcTex = texture;
3426ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        srcTex->AddRef();
3427ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    }
3428ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
3429ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    D3D11_BOX srcBox;
34301eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    srcBox.left   = static_cast<UINT>(safeArea.x);
34311eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    srcBox.right  = static_cast<UINT>(safeArea.x + safeArea.width);
34321eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    srcBox.top    = static_cast<UINT>(safeArea.y);
34331eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    srcBox.bottom = static_cast<UINT>(safeArea.y + safeArea.height);
34341eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    srcBox.front  = 0;
34351eb5bd76f18a1f4a78330c9dd30ecc99b91c6dc3Jamie Madill    srcBox.back   = 1;
3436ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
3437ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    mDeviceContext->CopySubresourceRegion(stagingTex, 0, 0, 0, 0, srcTex, subResource, &srcBox);
3438ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
3439ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(srcTex);
3440ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
34417538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill    PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0);
34427538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill    packPixels(stagingTex, packParams, pixels);
34437538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill
34447538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill    SafeRelease(stagingTex);
34457538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill}
34467538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill
34477538f7fa5f987fff945e7d9807dd345755f032bdJamie Madillvoid Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, void *pixelsOut)
34487538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill{
34497538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill    D3D11_TEXTURE2D_DESC textureDesc;
34507538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill    readTexture->GetDesc(&textureDesc);
34517538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill
3452ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    D3D11_MAPPED_SUBRESOURCE mapping;
34537538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill    HRESULT hr = mDeviceContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &mapping);
34549cd1915c96800fc998ec25b88b0e3081f0aa6109Geoff Lang    UNUSED_ASSERTION_VARIABLE(hr);
34557538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill    ASSERT(SUCCEEDED(hr));
3456ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
3457ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    unsigned char *source;
3458ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    int inputPitch;
34597538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill    if (params.pack.reverseRowOrder)
3460ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    {
34617538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill        source = static_cast<unsigned char*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1);
3462ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        inputPitch = -static_cast<int>(mapping.RowPitch);
3463ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    }
3464ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    else
3465ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    {
3466ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        source = static_cast<unsigned char*>(mapping.pData);
3467ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        inputPitch = static_cast<int>(mapping.RowPitch);
3468ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    }
3469ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
3470697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang    GLuint clientVersion = getCurrentClientVersion();
3471697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang
3472005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    GLenum sourceInternalFormat = d3d11_gl::GetInternalFormat(textureDesc.Format, clientVersion);
3473697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang    GLenum sourceFormat = gl::GetFormat(sourceInternalFormat, clientVersion);
3474697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang    GLenum sourceType = gl::GetType(sourceInternalFormat, clientVersion);
3475697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang
3476697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang    GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat, clientVersion);
3477697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang
34787538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill    if (sourceFormat == params.format && sourceType == params.type)
3479ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    {
34807538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill        unsigned char *dest = static_cast<unsigned char*>(pixelsOut) + params.offset;
34817538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill        for (int y = 0; y < params.area.height; y++)
3482ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        {
34837538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill            memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourcePixelSize);
3484ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        }
3485ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    }
3486697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang    else
3487676dc8f916e2cd6eae579932ad36a188efd9cb09shannon.woods%transgaming.com@gtempaccount.com    {
34887538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill        GLenum destInternalFormat = gl::GetSizedInternalFormat(params.format, params.type, clientVersion);
3489697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang        GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat, clientVersion);
3490676dc8f916e2cd6eae579932ad36a188efd9cb09shannon.woods%transgaming.com@gtempaccount.com
34917538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill        ColorCopyFunction fastCopyFunc = d3d11::GetFastCopyFunction(textureDesc.Format, params.format, params.type);
3492697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang        if (fastCopyFunc)
3493676dc8f916e2cd6eae579932ad36a188efd9cb09shannon.woods%transgaming.com@gtempaccount.com        {
3494697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang            // Fast copy is possible through some special function
34957538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill            for (int y = 0; y < params.area.height; y++)
3496676dc8f916e2cd6eae579932ad36a188efd9cb09shannon.woods%transgaming.com@gtempaccount.com            {
34977538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill                for (int x = 0; x < params.area.width; x++)
3498697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                {
34997538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill                    void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destPixelSize;
3500697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                    void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize;
3501697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang
3502697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                    fastCopyFunc(src, dest);
3503697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                }
3504676dc8f916e2cd6eae579932ad36a188efd9cb09shannon.woods%transgaming.com@gtempaccount.com            }
3505676dc8f916e2cd6eae579932ad36a188efd9cb09shannon.woods%transgaming.com@gtempaccount.com        }
3506697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang        else
3507ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        {
35089eeecfc20be089b62310787895870e0284cfb383Jamie Madill            ColorReadFunction readFunc = d3d11::GetColorReadFunction(textureDesc.Format);
35097538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill            ColorWriteFunction writeFunc = gl::GetColorWriteFunction(params.format, params.type, clientVersion);
3510697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang
3511697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang            unsigned char temp[16]; // Maximum size of any Color<T> type used.
3512697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang            META_ASSERT(sizeof(temp) >= sizeof(gl::ColorF)  &&
3513697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                        sizeof(temp) >= sizeof(gl::ColorUI) &&
3514697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                        sizeof(temp) >= sizeof(gl::ColorI));
3515697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang
35167538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill            for (int y = 0; y < params.area.height; y++)
3517ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com            {
35187538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill                for (int x = 0; x < params.area.width; x++)
3519697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                {
35207538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill                    void *dest = static_cast<unsigned char*>(pixelsOut) + params.offset + y * params.outputPitch + x * destPixelSize;
3521697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                    void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize;
3522697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang
3523697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                    // readFunc and writeFunc will be using the same type of color, CopyTexImage
3524697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                    // will not allow the copy otherwise.
3525697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                    readFunc(src, temp);
3526697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                    writeFunc(temp, dest);
3527697ad3ed5e022f1a47356111456e6ac030c0bd5eGeoff Lang                }
3528ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com            }
3529ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com        }
3530ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com    }
3531ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
35327538f7fa5f987fff945e7d9807dd345755f032bdJamie Madill    mDeviceContext->Unmap(readTexture, 0);
3533ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com}
3534ee42a0a066e2e1b2feb220e9f250b680b3536c40daniel@transgaming.com
3535758d5b2158ed4df145974c475df68a35bf476a00Geoff Langbool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
3536125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                      RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
3537125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                      bool colorBlit, bool depthBlit, bool stencilBlit)
35381e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com{
3539975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // Since blitRenderbufferRect is called for each render buffer that needs to be blitted,
3540975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // it should never be the case that both color and depth/stencil need to be blitted at
3541975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    // at the same time.
3542975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang    ASSERT(colorBlit != (depthBlit || stencilBlit));
3543975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang
3544c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang    bool result = true;
35451e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com
35464d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang    RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget);
35474d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang    if (!drawRenderTarget)
35484d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang    {
35494d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang        ERR("Failed to retrieve the draw render target from the draw framebuffer.");
35504d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang        return gl::error(GL_OUT_OF_MEMORY, false);
35514d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang    }
35524d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang
35534d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang    ID3D11Resource *drawTexture = drawRenderTarget11->getTexture();
35544d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang    unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex();
35554d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang    ID3D11RenderTargetView *drawRTV = drawRenderTarget11->getRenderTargetView();
35564d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang    ID3D11DepthStencilView *drawDSV = drawRenderTarget11->getDepthStencilView();
35574d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang
35581d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com    RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget);
35591d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com    if (!readRenderTarget)
35601e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    {
35611d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the read render target from the read framebuffer.");
3562ea4a0c6671ab0b079ed5e0313699742d1c6a9bd1shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
35631e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    }
35641e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com
356527ac40e8d6e580bfd2c70ccc06cc2ac84cc017b7shannon.woods%transgaming.com@gtempaccount.com    ID3D11Resource *readTexture = NULL;
3566c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang    ID3D11ShaderResourceView *readSRV = NULL;
35671d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com    unsigned int readSubresource = 0;
35681d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com    if (readRenderTarget->getSamples() > 0)
35691e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    {
357027ac40e8d6e580bfd2c70ccc06cc2ac84cc017b7shannon.woods%transgaming.com@gtempaccount.com        ID3D11Resource *unresolvedResource = readRenderTarget11->getTexture();
357127ac40e8d6e580bfd2c70ccc06cc2ac84cc017b7shannon.woods%transgaming.com@gtempaccount.com        ID3D11Texture2D *unresolvedTexture = d3d11::DynamicCastComObject<ID3D11Texture2D>(unresolvedResource);
35721e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com
357327ac40e8d6e580bfd2c70ccc06cc2ac84cc017b7shannon.woods%transgaming.com@gtempaccount.com        if (unresolvedTexture)
357427ac40e8d6e580bfd2c70ccc06cc2ac84cc017b7shannon.woods%transgaming.com@gtempaccount.com        {
357527ac40e8d6e580bfd2c70ccc06cc2ac84cc017b7shannon.woods%transgaming.com@gtempaccount.com            readTexture = resolveMultisampledTexture(unresolvedTexture, readRenderTarget11->getSubresourceIndex());
357627ac40e8d6e580bfd2c70ccc06cc2ac84cc017b7shannon.woods%transgaming.com@gtempaccount.com            readSubresource = 0;
35771e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com
3578ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang            SafeRelease(unresolvedTexture);
3579c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang
35805c9a29abb49d834262712aa461b8ecbfccf0c842Geoff Lang            HRESULT hresult = mDevice->CreateShaderResourceView(readTexture, NULL, &readSRV);
35815c9a29abb49d834262712aa461b8ecbfccf0c842Geoff Lang            if (FAILED(hresult))
3582c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang            {
3583ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang                SafeRelease(readTexture);
3584c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang                return gl::error(GL_OUT_OF_MEMORY, false);
3585c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang            }
358627ac40e8d6e580bfd2c70ccc06cc2ac84cc017b7shannon.woods%transgaming.com@gtempaccount.com        }
35871e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    }
35881e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    else
35891e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    {
35901d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        readTexture = readRenderTarget11->getTexture();
35914d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang        readTexture->AddRef();
35921d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        readSubresource = readRenderTarget11->getSubresourceIndex();
3593c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        readSRV = readRenderTarget11->getShaderResourceView();
35944d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang        readSRV->AddRef();
35951e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    }
35961e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com
35974d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang    if (!readTexture || !readSRV)
35981e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    {
35994d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang        SafeRelease(readTexture);
36004d782730ae55e551f3701fe58c29b39c1940665aGeoff Lang        SafeRelease(readSRV);
36011d64b62674b7c8898384599e0196100fb3cd5b11shannon.woods%transgaming.com@gtempaccount.com        ERR("Failed to retrieve the read render target view from the read render target.");
3602ea4a0c6671ab0b079ed5e0313699742d1c6a9bd1shannon.woods@transgaming.com        return gl::error(GL_OUT_OF_MEMORY, false);
36031e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com    }
36041e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com
3605125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
3606125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
3607125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
3608125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, NULL);
3609125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
3610125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    bool wholeBufferCopy = !scissorNeeded &&
3611125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                           readRect.x == 0 && readRect.width == readSize.width &&
3612125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                           readRect.y == 0 && readRect.height == readSize.height &&
3613125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                           drawRect.x == 0 && drawRect.width == drawSize.width &&
3614125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                           drawRect.y == 0 && drawRect.height == drawSize.height;
36151e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com
3616c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang    bool stretchRequired = readRect.width != drawRect.width || readRect.height != drawRect.height;
3617758d5b2158ed4df145974c475df68a35bf476a00Geoff Lang
36181cd1b213b5bdde92eccc469fb51a4cf071fdc2dfGeoff Lang    bool flipRequired = readRect.width < 0 || readRect.height < 0 || drawRect.width < 0 || drawRect.height < 0;
3619125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
3620125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    bool outOfBounds = readRect.x < 0 || readRect.x + readRect.width > readSize.width ||
3621125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                       readRect.y < 0 || readRect.y + readRect.height > readSize.height ||
3622125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                       drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width ||
3623125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                       drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height;
3624125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
3625125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    bool hasDepth = gl::GetDepthBits(drawRenderTarget11->getActualFormat(), getCurrentClientVersion()) > 0;
3626125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    bool hasStencil = gl::GetStencilBits(drawRenderTarget11->getActualFormat(), getCurrentClientVersion()) > 0;
3627125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    bool partialDSBlit = (hasDepth && depthBlit) != (hasStencil && stencilBlit);
3628125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
3629c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang    if (readRenderTarget11->getActualFormat() == drawRenderTarget->getActualFormat() &&
3630125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit &&
3631125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        (!(depthBlit || stencilBlit) || wholeBufferCopy))
3632c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang    {
3633125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        UINT dstX = drawRect.x;
3634125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        UINT dstY = drawRect.y;
3635125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
3636c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        D3D11_BOX readBox;
3637c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        readBox.left = readRect.x;
3638c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        readBox.right = readRect.x + readRect.width;
3639c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        readBox.top = readRect.y;
3640c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        readBox.bottom = readRect.y + readRect.height;
3641c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        readBox.front = 0;
3642c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        readBox.back = 1;
36431e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com
3644125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        if (scissorNeeded)
3645125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        {
3646125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            // drawRect is guaranteed to have positive width and height because stretchRequired is false.
3647125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            ASSERT(drawRect.width >= 0 || drawRect.height >= 0);
3648125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
3649125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            if (drawRect.x < scissor->x)
3650125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            {
3651125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                dstX = scissor->x;
3652125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                readBox.left += (scissor->x - drawRect.x);
3653125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            }
3654125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            if (drawRect.y < scissor->y)
3655125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            {
3656125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                dstY = scissor->y;
3657125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                readBox.top += (scissor->y - drawRect.y);
3658125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            }
3659125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            if (drawRect.x + drawRect.width > scissor->x + scissor->width)
3660125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            {
3661125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                readBox.right -= ((drawRect.x + drawRect.width) - (scissor->x + scissor->width));
3662125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            }
3663125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            if (drawRect.y + drawRect.height > scissor->y + scissor->height)
3664125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            {
3665125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                readBox.bottom -= ((drawRect.y + drawRect.height) - (scissor->y + scissor->height));
3666125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            }
3667125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        }
3668125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
3669c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox
3670c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        // We also require complete framebuffer copies for depth-stencil blit.
3671c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox;
36721e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com
3673125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, dstX, dstY, 0,
3674c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang                                              readTexture, readSubresource, pSrcBox);
3675c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        result = true;
3676c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang    }
3677c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang    else
3678c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang    {
3679c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        gl::Box readArea(readRect.x, readRect.y, 0, readRect.width, readRect.height, 1);
3680c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        gl::Box drawArea(drawRect.x, drawRect.y, 0, drawRect.width, drawRect.height, 1);
3681c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang
3682975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        if (depthBlit && stencilBlit)
3683975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        {
3684975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang            result = mBlit->copyDepthStencil(readTexture, readSubresource, readArea, readSize,
3685125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                             drawTexture, drawSubresource, drawArea, drawSize,
3686125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                             scissor);
3687975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        }
3688975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        else if (depthBlit)
3689975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        {
3690125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            result = mBlit->copyDepth(readSRV, readArea, readSize, drawDSV, drawArea, drawSize,
3691125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                      scissor);
3692975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        }
3693975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang        else if (stencilBlit)
3694c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        {
3695975af378b32445c4c0595de0ff3a64cb931c139aGeoff Lang            result = mBlit->copyStencil(readTexture, readSubresource, readArea, readSize,
3696125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                        drawTexture, drawSubresource, drawArea, drawSize,
3697125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                        scissor);
3698c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        }
3699c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        else
3700c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        {
3701685806d62991e99b9cde6e639a6a4b9263f28e70Geoff Lang            GLenum format = gl::GetFormat(drawRenderTarget->getInternalFormat(), getCurrentClientVersion());
3702125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            result = mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize,
3703125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                        scissor, format, filter);
3704c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang        }
3705c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang    }
3706c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang
3707c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang    SafeRelease(readTexture);
3708c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang    SafeRelease(readSRV);
3709c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang
3710c1f51be4fd80a09a41bfe6f6f65ee85262748574Geoff Lang    return result;
37111e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com}
37121e1deda4cf894ce5d1bd651d2f8de688f4b5358dshannon.woods@transgaming.com
3713d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.comID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource)
3714d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com{
3715d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com    D3D11_TEXTURE2D_DESC textureDesc;
3716d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com    source->GetDesc(&textureDesc);
3717d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com
3718d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com    if (textureDesc.SampleDesc.Count > 1)
3719d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com    {
3720d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        D3D11_TEXTURE2D_DESC resolveDesc;
3721d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        resolveDesc.Width = textureDesc.Width;
3722d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        resolveDesc.Height = textureDesc.Height;
3723d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        resolveDesc.MipLevels = 1;
3724d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        resolveDesc.ArraySize = 1;
3725d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        resolveDesc.Format = textureDesc.Format;
3726d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        resolveDesc.SampleDesc.Count = 1;
3727d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        resolveDesc.SampleDesc.Quality = 0;
3728d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        resolveDesc.Usage = textureDesc.Usage;
3729d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        resolveDesc.BindFlags = textureDesc.BindFlags;
3730d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        resolveDesc.CPUAccessFlags = 0;
3731d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        resolveDesc.MiscFlags = 0;
3732d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com
3733d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        ID3D11Texture2D *resolveTexture = NULL;
3734d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        HRESULT result = mDevice->CreateTexture2D(&resolveDesc, NULL, &resolveTexture);
3735d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        if (FAILED(result))
3736d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        {
3737d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com            ERR("Failed to create a multisample resolve texture, HRESULT: 0x%X.", result);
3738d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com            return NULL;
3739d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        }
3740d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com
3741d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        mDeviceContext->ResolveSubresource(resolveTexture, 0, source, subresource, textureDesc.Format);
3742d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        return resolveTexture;
3743d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com    }
3744d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com    else
3745d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com    {
3746d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        source->AddRef();
3747d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com        return source;
3748d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com    }
3749d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com}
3750d67f9ce00a1ff8289f330bb8ca9233fe38a48be2shannon.woods@transgaming.com
37513c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madillvoid Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel)
375242477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang{
37533c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    ASSERT(attachment->isTexture());
37543c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    TextureStorage *texStorage = attachment->getTextureStorage();
375542477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    if (texStorage)
375642477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    {
375742477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage);
375842477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        if (!texStorage11)
375942477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        {
376042477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang            ERR("texture storage pointer unexpectedly null.");
376142477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang            return;
376242477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        }
376342477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
376442477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        texStorage11->invalidateSwizzleCacheLevel(mipLevel);
376542477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    }
376642477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang}
376742477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
376842477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Langvoid Renderer11::invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer)
376942477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang{
377042477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
377142477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    {
37723c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(colorAttachment);
37733c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        if (attachment && attachment->isTexture())
377442477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        {
37753c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill            invalidateFBOAttachmentSwizzles(attachment, framebuffer->getColorbufferMipLevel(colorAttachment));
377642477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang        }
377742477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    }
377842477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
37793c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    gl::FramebufferAttachment *depthAttachment = framebuffer->getDepthbuffer();
37803c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    if (depthAttachment && depthAttachment->isTexture())
378142477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    {
37823c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        invalidateFBOAttachmentSwizzles(depthAttachment, framebuffer->getDepthbufferMipLevel());
378342477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    }
378442477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
37853c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    gl::FramebufferAttachment *stencilAttachment = framebuffer->getStencilbuffer();
37863c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    if (stencilAttachment && stencilAttachment->isTexture())
378742477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    {
37883c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        invalidateFBOAttachmentSwizzles(stencilAttachment, framebuffer->getStencilbufferMipLevel());
378942477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang    }
379042477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang}
379142477a430c09c50e19044a2ef99ebbb3efd68a38Geoff Lang
37926e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.orgbool Renderer11::getLUID(LUID *adapterLuid) const
37936e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org{
37946e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org    adapterLuid->HighPart = 0;
37956e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org    adapterLuid->LowPart = 0;
37966e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org
37976e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org    if (!mDxgiAdapter)
37986e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org    {
37996e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org        return false;
38006e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org    }
38016e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org
38026e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org    DXGI_ADAPTER_DESC adapterDesc;
38036e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org    if (FAILED(mDxgiAdapter->GetDesc(&adapterDesc)))
38046e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org    {
38056e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org        return false;
38066e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org    }
38076e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org
38086e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org    *adapterLuid = adapterDesc.AdapterLuid;
38096e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org    return true;
38106e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org}
38116e4f2a6b70e12750a1e79c3dcee6c6dd5cfb67feshannonwoods@chromium.org
3812005df41f8900641ed1df60700c8e2eca659a33cbGeoff LangGLenum Renderer11::getNativeTextureFormat(GLenum internalFormat) const
3813c8c102b5f78e897c02de8b7117a64fab27163ff1Jamie Madill{
3814c8c102b5f78e897c02de8b7117a64fab27163ff1Jamie Madill    int clientVersion = getCurrentClientVersion();
3815c8c102b5f78e897c02de8b7117a64fab27163ff1Jamie Madill    return d3d11_gl::GetInternalFormat(gl_d3d11::GetTexFormat(internalFormat, clientVersion), clientVersion);
3816c8c102b5f78e897c02de8b7117a64fab27163ff1Jamie Madill}
3817c8c102b5f78e897c02de8b7117a64fab27163ff1Jamie Madill
381895ffb8683f3bf1874f0b4c41491633098ee08ab7Jamie Madillrx::VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
381995ffb8683f3bf1874f0b4c41491633098ee08ab7Jamie Madill{
382095ffb8683f3bf1874f0b4c41491633098ee08ab7Jamie Madill    return gl_d3d11::GetVertexConversionType(vertexFormat);
382195ffb8683f3bf1874f0b4c41491633098ee08ab7Jamie Madill}
382295ffb8683f3bf1874f0b4c41491633098ee08ab7Jamie Madill
382395ffb8683f3bf1874f0b4c41491633098ee08ab7Jamie MadillGLenum Renderer11::getVertexComponentType(const gl::VertexFormat &vertexFormat) const
382495ffb8683f3bf1874f0b4c41491633098ee08ab7Jamie Madill{
382595ffb8683f3bf1874f0b4c41491633098ee08ab7Jamie Madill    return d3d11::GetComponentType(gl_d3d11::GetNativeVertexFormat(vertexFormat));
382695ffb8683f3bf1874f0b4c41491633098ee08ab7Jamie Madill}
382795ffb8683f3bf1874f0b4c41491633098ee08ab7Jamie Madill
382861e49a5cacc894fe2de1273c65374a5e7083a05fGeoff LangRenderer11::MultisampleSupportInfo Renderer11::getMultisampleSupportInfo(DXGI_FORMAT format)
382961e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang{
383061e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang    MultisampleSupportInfo supportInfo = { 0 };
383161e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang
383261e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang    UINT formatSupport;
383361e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang    HRESULT result;
383461e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang
383561e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang    result = mDevice->CheckFormatSupport(format, &formatSupport);
383661e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang    if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET))
383761e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang    {
383861e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang        for (unsigned int i = 1; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
383961e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang        {
384061e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang            result = mDevice->CheckMultisampleQualityLevels(format, i, &supportInfo.qualityLevels[i - 1]);
384161e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang            if (SUCCEEDED(result) && supportInfo.qualityLevels[i - 1] > 0)
384261e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang            {
384361e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang                supportInfo.maxSupportedSamples = std::max(supportInfo.maxSupportedSamples, i);
384461e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang            }
384561e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang            else
384661e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang            {
384761e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang                supportInfo.qualityLevels[i - 1] = 0;
384861e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang            }
384961e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang        }
385061e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang    }
385161e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang
385261e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang    return supportInfo;
385361e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang}
385461e49a5cacc894fe2de1273c65374a5e7083a05fGeoff Lang
38559d971ffdc1f6a082980e4a6ec4cd9c6e695460e8shannon.woods@transgaming.com}
3856