src/render/direct3d11/SDL_render_d3d11.c
author David Ludwig <dludwig@pobox.com>
Wed, 30 Apr 2014 21:12:47 -0400
changeset 8748 7ba9c0a0cad7
parent 8728 c7174f961388
child 8755 f2fc45874b9c
permissions -rw-r--r--
WinRT: suppressed an unused param warning when building for Windows Phone 8.1
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "../../SDL_internal.h"
    22 
    23 #if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
    24 
    25 #define COBJMACROS
    26 #include "../../core/windows/SDL_windows.h"
    27 #include "SDL_hints.h"
    28 #include "SDL_loadso.h"
    29 #include "SDL_syswm.h"
    30 #include "../SDL_sysrender.h"
    31 #include "../SDL_d3dmath.h"
    32 
    33 #include <d3d11_1.h>
    34 
    35 
    36 #ifdef __WINRT__
    37 
    38 #if NTDDI_VERSION > NTDDI_WIN8
    39 #include <DXGI1_3.h>
    40 #endif
    41 
    42 #include "SDL_render_winrt.h"
    43 
    44 #if WINAPI_FAMILY == WINAPI_FAMILY_APP
    45 #include <windows.ui.xaml.media.dxinterop.h>
    46 /* TODO, WinRT, XAML: get the ISwapChainBackgroundPanelNative from something other than a global var */
    47 extern ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative;
    48 #endif  /* WINAPI_FAMILY == WINAPI_FAMILY_APP */
    49 
    50 #endif  /* __WINRT__ */
    51 
    52 
    53 #define SAFE_RELEASE(X) if ((X)) { IUnknown_Release(SDL_static_cast(IUnknown*, X)); X = NULL; }
    54 
    55 
    56 /* Vertex shader, common values */
    57 typedef struct
    58 {
    59     Float4X4 model;
    60     Float4X4 projectionAndView;
    61 } VertexShaderConstants;
    62 
    63 /* Per-vertex data */
    64 typedef struct
    65 {
    66     Float3 pos;
    67     Float2 tex;
    68     Float4 color;
    69 } VertexPositionColor;
    70 
    71 /* Per-texture data */
    72 typedef struct
    73 {
    74     ID3D11Texture2D *mainTexture;
    75     ID3D11ShaderResourceView *mainTextureResourceView;
    76     ID3D11RenderTargetView *mainTextureRenderTargetView;
    77     ID3D11Texture2D *stagingTexture;
    78     int lockedTexturePositionX;
    79     int lockedTexturePositionY;
    80     D3D11_FILTER scaleMode;
    81 
    82     /* YV12 texture support */
    83     SDL_bool yuv;
    84     ID3D11Texture2D *mainTextureU;
    85     ID3D11ShaderResourceView *mainTextureResourceViewU;
    86     ID3D11Texture2D *mainTextureV;
    87     ID3D11ShaderResourceView *mainTextureResourceViewV;
    88     Uint8 *pixels;
    89     int pitch;
    90     SDL_Rect locked_rect;
    91 } D3D11_TextureData;
    92 
    93 /* Private renderer data */
    94 typedef struct
    95 {
    96     void *hDXGIMod;
    97     void *hD3D11Mod;
    98     IDXGIFactory2 *dxgiFactory;
    99     IDXGIAdapter *dxgiAdapter;
   100     ID3D11Device1 *d3dDevice;
   101     ID3D11DeviceContext1 *d3dContext;
   102     IDXGISwapChain1 *swapChain;
   103     DXGI_SWAP_EFFECT swapEffect;
   104     ID3D11RenderTargetView *mainRenderTargetView;
   105     ID3D11RenderTargetView *currentOffscreenRenderTargetView;
   106     ID3D11InputLayout *inputLayout;
   107     ID3D11Buffer *vertexBuffer;
   108     ID3D11VertexShader *vertexShader;
   109     ID3D11PixelShader *colorPixelShader;
   110     ID3D11PixelShader *texturePixelShader;
   111     ID3D11PixelShader *yuvPixelShader;
   112     ID3D11BlendState *blendModeBlend;
   113     ID3D11BlendState *blendModeAdd;
   114     ID3D11BlendState *blendModeMod;
   115     ID3D11SamplerState *nearestPixelSampler;
   116     ID3D11SamplerState *linearSampler;
   117     D3D_FEATURE_LEVEL featureLevel;
   118 
   119     /* Rasterizers */
   120     ID3D11RasterizerState *mainRasterizer;
   121     ID3D11RasterizerState *clippedRasterizer;
   122 
   123     /* Vertex buffer constants */
   124     VertexShaderConstants vertexShaderConstantsData;
   125     ID3D11Buffer *vertexShaderConstants;
   126 
   127     /* Cached renderer properties */
   128     DXGI_MODE_ROTATION rotation;
   129     ID3D11RenderTargetView *currentRenderTargetView;
   130     ID3D11RasterizerState *currentRasterizerState;
   131     ID3D11BlendState *currentBlendState;
   132     ID3D11PixelShader *currentShader;
   133     ID3D11ShaderResourceView *currentShaderResource;
   134     ID3D11SamplerState *currentSampler;
   135 } D3D11_RenderData;
   136 
   137 
   138 /* Defined here so we don't have to include uuid.lib */
   139 static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };
   140 static const GUID IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } };
   141 static const GUID IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } };
   142 static const GUID IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } };
   143 static const GUID IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } };
   144 static const GUID IID_ID3D11DeviceContext1 = { 0xbb2c6faa, 0xb5fb, 0x4082, { 0x8e, 0x6b, 0x38, 0x8b, 0x8c, 0xfa, 0x90, 0xe1 } };
   145 static const GUID IID_ID3D11Debug = { 0x79cf2233, 0x7536, 0x4948, { 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } };
   146 
   147 /* Direct3D 11.x shaders
   148 
   149    SDL's shaders are compiled into SDL itself, to simplify distribution.
   150 
   151    All Direct3D 11.x shaders were compiled with the following:
   152 
   153    fxc /E"main" /T "<TYPE>" /Fo"<OUTPUT FILE>" "<INPUT FILE>"
   154 
   155      Variables:
   156      - <TYPE>: the type of shader.  A table of utilized shader types is
   157        listed below.
   158      - <OUTPUT FILE>: where to store compiled output
   159      - <INPUT FILE>: where to read shader source code from
   160 
   161      Shader types:
   162      - ps_4_0_level_9_1: Pixel shader for Windows 8+, including Windows RT
   163      - vs_4_0_level_9_1: Vertex shader for Windows 8+, including Windows RT
   164      - ps_4_0_level_9_3: Pixel shader for Windows Phone 8
   165      - vs_4_0_level_9_3: Vertex shader for Windows Phone 8
   166    
   167 
   168    Shader object code was converted to a list of DWORDs via the following
   169    *nix style command (available separately from Windows + MSVC):
   170 
   171      hexdump -v -e '6/4 "0x%08.8x, " "\n"' <FILE>
   172   */
   173 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
   174 #define D3D11_USE_SHADER_MODEL_4_0_level_9_3
   175 #else
   176 #define D3D11_USE_SHADER_MODEL_4_0_level_9_1
   177 #endif
   178 
   179 /* The color-only-rendering pixel shader:
   180 
   181    --- D3D11_PixelShader_Colors.hlsl ---
   182    struct PixelShaderInput
   183    {
   184        float4 pos : SV_POSITION;
   185        float2 tex : TEXCOORD0;
   186        float4 color : COLOR0;
   187    };
   188 
   189    float4 main(PixelShaderInput input) : SV_TARGET
   190    {
   191        return input.color;
   192    }
   193 */
   194 #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
   195 static const DWORD D3D11_PixelShader_Colors[] = {
   196     0x43425844, 0xd74c28fe, 0xa1eb8804, 0x269d512a, 0x7699723d, 0x00000001,
   197     0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140,
   198     0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200,
   199     0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000,
   200     0x00240000, 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001,
   201     0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040,
   202     0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2,
   203     0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002,
   204     0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000,
   205     0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
   206     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   207     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000,
   208     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   209     0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000,
   210     0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d,
   211     0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072,
   212     0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438,
   213     0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
   214     0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
   215     0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000,
   216     0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
   217     0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
   218     0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
   219     0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
   220 };
   221 #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
   222 static const DWORD D3D11_PixelShader_Colors[] = {
   223     0x43425844, 0x93f6ccfc, 0x5f919270, 0x7a11aa4f, 0x9148e931, 0x00000001,
   224     0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140,
   225     0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200,
   226     0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000,
   227     0x00240000, 0xffff0201, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001,
   228     0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040,
   229     0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2,
   230     0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002,
   231     0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000,
   232     0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
   233     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   234     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000,
   235     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   236     0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000,
   237     0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d,
   238     0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072,
   239     0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438,
   240     0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
   241     0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
   242     0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000,
   243     0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
   244     0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
   245     0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
   246     0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
   247 };
   248 #else
   249 #error "An appropriate 'colors' pixel shader is not defined."
   250 #endif
   251 
   252 /* The texture-rendering pixel shader:
   253 
   254     --- D3D11_PixelShader_Textures.hlsl ---
   255     Texture2D theTexture : register(t0);
   256     SamplerState theSampler : register(s0);
   257 
   258     struct PixelShaderInput
   259     {
   260         float4 pos : SV_POSITION;
   261         float2 tex : TEXCOORD0;
   262         float4 color : COLOR0;
   263     };
   264 
   265     float4 main(PixelShaderInput input) : SV_TARGET
   266     {
   267         return theTexture.Sample(theSampler, input.tex) * input.color;
   268     }
   269 */
   270 #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
   271 static const DWORD D3D11_PixelShader_Textures[] = {
   272     0x43425844, 0x6299b59f, 0x155258f2, 0x873ab86a, 0xfcbb6dcd, 0x00000001,
   273     0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8,
   274     0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200,
   275     0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001,
   276     0x00280000, 0x00000000, 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000,
   277     0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800,
   278     0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000,
   279     0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff,
   280     0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000,
   281     0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062,
   282     0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065,
   283     0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2,
   284     0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000,
   285     0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
   286     0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003,
   287     0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000,
   288     0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   289     0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   290     0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   291     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8,
   292     0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100,
   293     0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
   294     0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005,
   295     0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874,
   296     0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263,
   297     0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43,
   298     0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00,
   299     0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
   300     0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
   301     0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000,
   302     0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
   303     0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
   304     0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
   305     0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
   306 };
   307 #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
   308 static const DWORD D3D11_PixelShader_Textures[] = {
   309     0x43425844, 0x5876569a, 0x01b6c87e, 0x8447454f, 0xc7f3ef10, 0x00000001,
   310     0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8,
   311     0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200,
   312     0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001,
   313     0x00280000, 0x00000000, 0xffff0201, 0x0200001f, 0x80000000, 0xb0030000,
   314     0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800,
   315     0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000,
   316     0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff,
   317     0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000,
   318     0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062,
   319     0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065,
   320     0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2,
   321     0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000,
   322     0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
   323     0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003,
   324     0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000,
   325     0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   326     0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   327     0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   328     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8,
   329     0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100,
   330     0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
   331     0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005,
   332     0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874,
   333     0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263,
   334     0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43,
   335     0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00,
   336     0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
   337     0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
   338     0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000,
   339     0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
   340     0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
   341     0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
   342     0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
   343 };
   344 #else
   345 #error "An appropriate 'textures' pixel shader is not defined"
   346 #endif
   347 
   348 /* The yuv-rendering pixel shader:
   349 
   350     --- D3D11_PixelShader_YUV.hlsl ---
   351     Texture2D theTextureY : register(t0);
   352     Texture2D theTextureU : register(t1);
   353     Texture2D theTextureV : register(t2);
   354     SamplerState theSampler : register(s0);
   355 
   356     struct PixelShaderInput
   357     {
   358         float4 pos : SV_POSITION;
   359         float2 tex : TEXCOORD0;
   360         float4 color : COLOR0;
   361     };
   362 
   363     float4 main(PixelShaderInput input) : SV_TARGET
   364     {
   365         const float3 offset = {-0.0625, -0.5, -0.5};
   366         const float3 Rcoeff = {1.164,  0.000,  1.596};
   367         const float3 Gcoeff = {1.164, -0.391, -0.813};
   368         const float3 Bcoeff = {1.164,  2.018,  0.000};
   369 
   370         float4 Output;
   371 
   372         float3 yuv;
   373         yuv.x = theTextureY.Sample(theSampler, input.tex).r;
   374         yuv.y = theTextureU.Sample(theSampler, input.tex).r;
   375         yuv.z = theTextureV.Sample(theSampler, input.tex).r;
   376 
   377         yuv += offset;
   378         Output.r = dot(yuv, Rcoeff);
   379         Output.g = dot(yuv, Gcoeff);
   380         Output.b = dot(yuv, Bcoeff);
   381         Output.a = 1.0f;
   382 
   383         return Output * input.color;
   384     }
   385 
   386 */
   387 #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
   388 static const DWORD D3D11_PixelShader_YUV[] = {
   389     0x43425844, 0x04e69cba, 0x74ce6dd2, 0x7fcf84cb, 0x3003d677, 0x00000001,
   390     0x000005e8, 0x00000006, 0x00000038, 0x000001dc, 0x000003bc, 0x00000438,
   391     0x00000540, 0x000005b4, 0x396e6f41, 0x0000019c, 0x0000019c, 0xffff0200,
   392     0x0000016c, 0x00000030, 0x00300000, 0x00300000, 0x00300000, 0x00240003,
   393     0x00300000, 0x00000000, 0x00010001, 0x00020002, 0xffff0200, 0x05000051,
   394     0xa00f0000, 0xbd800000, 0xbf000000, 0xbf000000, 0x3f800000, 0x05000051,
   395     0xa00f0001, 0x3f94fdf4, 0x3fcc49ba, 0x00000000, 0x00000000, 0x05000051,
   396     0xa00f0002, 0x3f94fdf4, 0xbec83127, 0xbf5020c5, 0x00000000, 0x05000051,
   397     0xa00f0003, 0x3f94fdf4, 0x400126e9, 0x00000000, 0x00000000, 0x0200001f,
   398     0x80000000, 0xb0030000, 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f,
   399     0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f,
   400     0x90000000, 0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,
   401     0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, 0x03000042, 0x800f0002,
   402     0xb0e40000, 0xa0e40802, 0x02000001, 0x80020000, 0x80000001, 0x02000001,
   403     0x80040000, 0x80000002, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40000,
   404     0x03000005, 0x80080000, 0x80000000, 0xa0000001, 0x04000004, 0x80010001,
   405     0x80aa0000, 0xa0550001, 0x80ff0000, 0x03000008, 0x80020001, 0x80e40000,
   406     0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000, 0xa0e40003, 0xa0aa0003,
   407     0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40001,
   408     0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, 0x52444853,
   409     0x000001d8, 0x00000040, 0x00000076, 0x0300005a, 0x00106000, 0x00000000,
   410     0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000,
   411     0x00000001, 0x00005555, 0x04001858, 0x00107000, 0x00000002, 0x00005555,
   412     0x03001062, 0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002,
   413     0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x09000045,
   414     0x001000f2, 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000,
   415     0x00106000, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00101046,
   416     0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000000, 0x05000036,
   417     0x00100022, 0x00000000, 0x0010000a, 0x00000001, 0x09000045, 0x001000f2,
   418     0x00000001, 0x00101046, 0x00000001, 0x00107e46, 0x00000002, 0x00106000,
   419     0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x0010000a, 0x00000001,
   420     0x0a000000, 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00004002,
   421     0xbd800000, 0xbf000000, 0xbf000000, 0x00000000, 0x0a00000f, 0x00100012,
   422     0x00000001, 0x00100086, 0x00000000, 0x00004002, 0x3f94fdf4, 0x3fcc49ba,
   423     0x00000000, 0x00000000, 0x0a000010, 0x00100022, 0x00000001, 0x00100246,
   424     0x00000000, 0x00004002, 0x3f94fdf4, 0xbec83127, 0xbf5020c5, 0x00000000,
   425     0x0a00000f, 0x00100042, 0x00000001, 0x00100046, 0x00000000, 0x00004002,
   426     0x3f94fdf4, 0x400126e9, 0x00000000, 0x00000000, 0x05000036, 0x00100082,
   427     0x00000001, 0x00004001, 0x3f800000, 0x07000038, 0x001020f2, 0x00000000,
   428     0x00100e46, 0x00000001, 0x00101e46, 0x00000002, 0x0100003e, 0x54415453,
   429     0x00000074, 0x0000000c, 0x00000002, 0x00000000, 0x00000003, 0x00000005,
   430     0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
   431     0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000,
   432     0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
   433     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   434     0x46454452, 0x00000100, 0x00000000, 0x00000000, 0x00000004, 0x0000001c,
   435     0xffff0400, 0x00000100, 0x000000cb, 0x0000009c, 0x00000003, 0x00000000,
   436     0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a7,
   437     0x00000002, 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001,
   438     0x0000000d, 0x000000b3, 0x00000002, 0x00000005, 0x00000004, 0xffffffff,
   439     0x00000001, 0x00000001, 0x0000000d, 0x000000bf, 0x00000002, 0x00000005,
   440     0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x53656874,
   441     0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x74005965, 0x65546568,
   442     0x72757478, 0x74005565, 0x65546568, 0x72757478, 0x4d005665, 0x6f726369,
   443     0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320,
   444     0x656c6970, 0x2e362072, 0x36392e33, 0x312e3030, 0x34383336, 0xababab00,
   445     0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
   446     0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
   447     0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000,
   448     0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
   449     0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
   450     0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
   451     0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
   452 };
   453 #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
   454 static const DWORD D3D11_PixelShader_YUV[] = {
   455     0x43425844, 0xe6d969fc, 0x63cac33c, 0xa4926502, 0x5d788135, 0x00000001,
   456     0x000005c0, 0x00000006, 0x00000038, 0x000001b4, 0x00000394, 0x00000410,
   457     0x00000518, 0x0000058c, 0x396e6f41, 0x00000174, 0x00000174, 0xffff0200,
   458     0x00000144, 0x00000030, 0x00300000, 0x00300000, 0x00300000, 0x00240003,
   459     0x00300000, 0x00000000, 0x00010001, 0x00020002, 0xffff0201, 0x05000051,
   460     0xa00f0000, 0xbd800000, 0xbf000000, 0x3f800000, 0x00000000, 0x05000051,
   461     0xa00f0001, 0x3f94fdf4, 0x3fcc49ba, 0x00000000, 0x400126e9, 0x05000051,
   462     0xa00f0002, 0x3f94fdf4, 0xbec83127, 0xbf5020c5, 0x00000000, 0x0200001f,
   463     0x80000000, 0xb0030000, 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f,
   464     0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f,
   465     0x90000000, 0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40801,
   466     0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40800, 0x02000001, 0x80020001,
   467     0x80000000, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40802, 0x02000001,
   468     0x80040001, 0x80000000, 0x03000002, 0x80070000, 0x80e40001, 0xa0d40000,
   469     0x0400005a, 0x80010001, 0x80e80000, 0xa0e40001, 0xa0aa0001, 0x03000008,
   470     0x80020001, 0x80e40000, 0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000,
   471     0xa0ec0001, 0xa0aa0001, 0x02000001, 0x80080001, 0xa0aa0000, 0x03000005,
   472     0x800f0000, 0x80e40001, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000,
   473     0x0000ffff, 0x52444853, 0x000001d8, 0x00000040, 0x00000076, 0x0300005a,
   474     0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555,
   475     0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, 0x00107000,
   476     0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03001062,
   477     0x001010f2, 0x00000002, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
   478     0x00000002, 0x09000045, 0x001000f2, 0x00000000, 0x00101046, 0x00000001,
   479     0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x09000045, 0x001000f2,
   480     0x00000001, 0x00101046, 0x00000001, 0x00107e46, 0x00000001, 0x00106000,
   481     0x00000000, 0x05000036, 0x00100022, 0x00000000, 0x0010000a, 0x00000001,
   482     0x09000045, 0x001000f2, 0x00000001, 0x00101046, 0x00000001, 0x00107e46,
   483     0x00000002, 0x00106000, 0x00000000, 0x05000036, 0x00100042, 0x00000000,
   484     0x0010000a, 0x00000001, 0x0a000000, 0x00100072, 0x00000000, 0x00100246,
   485     0x00000000, 0x00004002, 0xbd800000, 0xbf000000, 0xbf000000, 0x00000000,
   486     0x0a00000f, 0x00100012, 0x00000001, 0x00100086, 0x00000000, 0x00004002,
   487     0x3f94fdf4, 0x3fcc49ba, 0x00000000, 0x00000000, 0x0a000010, 0x00100022,
   488     0x00000001, 0x00100246, 0x00000000, 0x00004002, 0x3f94fdf4, 0xbec83127,
   489     0xbf5020c5, 0x00000000, 0x0a00000f, 0x00100042, 0x00000001, 0x00100046,
   490     0x00000000, 0x00004002, 0x3f94fdf4, 0x400126e9, 0x00000000, 0x00000000,
   491     0x05000036, 0x00100082, 0x00000001, 0x00004001, 0x3f800000, 0x07000038,
   492     0x001020f2, 0x00000000, 0x00100e46, 0x00000001, 0x00101e46, 0x00000002,
   493     0x0100003e, 0x54415453, 0x00000074, 0x0000000c, 0x00000002, 0x00000000,
   494     0x00000003, 0x00000005, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
   495     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
   496     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
   497     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   498     0x00000000, 0x00000000, 0x46454452, 0x00000100, 0x00000000, 0x00000000,
   499     0x00000004, 0x0000001c, 0xffff0400, 0x00000100, 0x000000cb, 0x0000009c,
   500     0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
   501     0x00000001, 0x000000a7, 0x00000002, 0x00000005, 0x00000004, 0xffffffff,
   502     0x00000000, 0x00000001, 0x0000000d, 0x000000b3, 0x00000002, 0x00000005,
   503     0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000bf,
   504     0x00000002, 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001,
   505     0x0000000d, 0x53656874, 0x6c706d61, 0x74007265, 0x65546568, 0x72757478,
   506     0x74005965, 0x65546568, 0x72757478, 0x74005565, 0x65546568, 0x72757478,
   507     0x4d005665, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c,
   508     0x72656461, 0x6d6f4320, 0x656c6970, 0x2e362072, 0x36392e33, 0x312e3030,
   509     0x34383336, 0xababab00, 0x4e475349, 0x0000006c, 0x00000003, 0x00000008,
   510     0x00000050, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f,
   511     0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303,
   512     0x00000065, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f,
   513     0x505f5653, 0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300,
   514     0xab00524f, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
   515     0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653,
   516     0x45475241, 0xabab0054
   517 };
   518 #else
   519 #error "An appropriate 'yuv' pixel shader is not defined."
   520 #endif
   521 
   522 /* The sole vertex shader:
   523 
   524    --- D3D11_VertexShader.hlsl ---
   525    #pragma pack_matrix( row_major )
   526 
   527    cbuffer VertexShaderConstants : register(b0)
   528    {
   529        matrix model;
   530        matrix projectionAndView;
   531    };
   532 
   533    struct VertexShaderInput
   534    {
   535        float3 pos : POSITION;
   536        float2 tex : TEXCOORD0;
   537        float4 color : COLOR0;
   538    };
   539 
   540    struct VertexShaderOutput
   541    {
   542        float4 pos : SV_POSITION;
   543        float2 tex : TEXCOORD0;
   544        float4 color : COLOR0;
   545    };
   546 
   547    VertexShaderOutput main(VertexShaderInput input)
   548    {
   549        VertexShaderOutput output;
   550        float4 pos = float4(input.pos, 1.0f);
   551 
   552        // Transform the vertex position into projected space.
   553        pos = mul(pos, model);
   554        pos = mul(pos, projectionAndView);
   555        output.pos = pos;
   556 
   557        // Pass through texture coordinates and color values without transformation
   558        output.tex = input.tex;
   559        output.color = input.color;
   560 
   561        return output;
   562    }
   563 */
   564 #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
   565 static const DWORD D3D11_VertexShader[] = {
   566     0x43425844, 0x62dfae5f, 0x3e8bd8df, 0x9ec97127, 0x5044eefb, 0x00000001,
   567     0x00000598, 0x00000006, 0x00000038, 0x0000016c, 0x00000334, 0x000003b0,
   568     0x000004b4, 0x00000524, 0x396e6f41, 0x0000012c, 0x0000012c, 0xfffe0200,
   569     0x000000f8, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000,
   570     0x00300001, 0x00000000, 0x00010008, 0x00000000, 0x00000000, 0xfffe0200,
   571     0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001,
   572     0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000,
   573     0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000,
   574     0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002,
   575     0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000,
   576     0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001,
   577     0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004,
   578     0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x04000004, 0xc0030000,
   579     0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, 0x80e40000,
   580     0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, 0x90e40002,
   581     0x0000ffff, 0x52444853, 0x000001c0, 0x00010040, 0x00000070, 0x04000059,
   582     0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x00101072, 0x00000000,
   583     0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, 0x00000002,
   584     0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032,
   585     0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000002,
   586     0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46,
   587     0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006,
   588     0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000,
   589     0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, 0x00208e46,
   590     0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, 0x001000f2,
   591     0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000003,
   592     0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46,
   593     0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, 0x00100006,
   594     0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, 0x00000001,
   595     0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, 0x00208e46,
   596     0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2,
   597     0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000007,
   598     0x00100e46, 0x00000001, 0x05000036, 0x00102032, 0x00000001, 0x00101046,
   599     0x00000001, 0x05000036, 0x001020f2, 0x00000002, 0x00101e46, 0x00000002,
   600     0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000,
   601     0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
   602     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   603     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
   604     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   605     0x00000000, 0x00000000, 0x46454452, 0x000000fc, 0x00000001, 0x00000054,
   606     0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000c6, 0x0000003c,
   607     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
   608     0x00000001, 0x74726556, 0x68537865, 0x72656461, 0x736e6f43, 0x746e6174,
   609     0xabab0073, 0x0000003c, 0x00000002, 0x0000006c, 0x00000080, 0x00000000,
   610     0x00000000, 0x0000009c, 0x00000000, 0x00000040, 0x00000002, 0x000000a4,
   611     0x00000000, 0x000000b4, 0x00000040, 0x00000040, 0x00000002, 0x000000a4,
   612     0x00000000, 0x65646f6d, 0xabab006c, 0x00030002, 0x00040004, 0x00000000,
   613     0x00000000, 0x6a6f7270, 0x69746365, 0x6e416e6f, 0x65695664, 0x694d0077,
   614     0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564,
   615     0x706d6f43, 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336,
   616     0xababab00, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
   617     0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x00000059,
   618     0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000062,
   619     0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x49534f50,
   620     0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, 0x00524f4c, 0x4e47534f,
   621     0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001,
   622     0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000,
   623     0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000,
   624     0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
   625     0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f
   626 };
   627 #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
   628 static const DWORD D3D11_VertexShader[] = {
   629     0x43425844, 0x01a24e41, 0x696af551, 0x4b2a87d1, 0x82ea03f6, 0x00000001,
   630     0x00000598, 0x00000006, 0x00000038, 0x0000016c, 0x00000334, 0x000003b0,
   631     0x000004b4, 0x00000524, 0x396e6f41, 0x0000012c, 0x0000012c, 0xfffe0200,
   632     0x000000f8, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000,
   633     0x00300001, 0x00000000, 0x00010008, 0x00000000, 0x00000000, 0xfffe0201,
   634     0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001,
   635     0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000,
   636     0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000,
   637     0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002,
   638     0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000,
   639     0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001,
   640     0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004,
   641     0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x04000004, 0xc0030000,
   642     0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, 0x80e40000,
   643     0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, 0x90e40002,
   644     0x0000ffff, 0x52444853, 0x000001c0, 0x00010040, 0x00000070, 0x04000059,
   645     0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x00101072, 0x00000000,
   646     0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, 0x00000002,
   647     0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032,
   648     0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000002,
   649     0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46,
   650     0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006,
   651     0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000,
   652     0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, 0x00208e46,
   653     0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, 0x001000f2,
   654     0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000003,
   655     0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46,
   656     0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, 0x00100006,
   657     0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, 0x00000001,
   658     0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, 0x00208e46,
   659     0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2,
   660     0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000007,
   661     0x00100e46, 0x00000001, 0x05000036, 0x00102032, 0x00000001, 0x00101046,
   662     0x00000001, 0x05000036, 0x001020f2, 0x00000002, 0x00101e46, 0x00000002,
   663     0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000,
   664     0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
   665     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   666     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
   667     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   668     0x00000000, 0x00000000, 0x46454452, 0x000000fc, 0x00000001, 0x00000054,
   669     0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000c6, 0x0000003c,
   670     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
   671     0x00000001, 0x74726556, 0x68537865, 0x72656461, 0x736e6f43, 0x746e6174,
   672     0xabab0073, 0x0000003c, 0x00000002, 0x0000006c, 0x00000080, 0x00000000,
   673     0x00000000, 0x0000009c, 0x00000000, 0x00000040, 0x00000002, 0x000000a4,
   674     0x00000000, 0x000000b4, 0x00000040, 0x00000040, 0x00000002, 0x000000a4,
   675     0x00000000, 0x65646f6d, 0xabab006c, 0x00030002, 0x00040004, 0x00000000,
   676     0x00000000, 0x6a6f7270, 0x69746365, 0x6e416e6f, 0x65695664, 0x694d0077,
   677     0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564,
   678     0x706d6f43, 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336,
   679     0xababab00, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
   680     0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x00000059,
   681     0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000062,
   682     0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x49534f50,
   683     0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, 0x00524f4c, 0x4e47534f,
   684     0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001,
   685     0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000,
   686     0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000,
   687     0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
   688     0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f
   689 };
   690 #else
   691 #error "An appropriate vertex shader is not defined."
   692 #endif
   693 
   694 
   695 /* Direct3D 11.1 renderer implementation */
   696 static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags);
   697 static void D3D11_WindowEvent(SDL_Renderer * renderer,
   698                             const SDL_WindowEvent *event);
   699 static int D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
   700 static int D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   701                              const SDL_Rect * rect, const void *srcPixels,
   702                              int srcPitch);
   703 static int D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
   704                                   const SDL_Rect * rect,
   705                                   const Uint8 *Yplane, int Ypitch,
   706                                   const Uint8 *Uplane, int Upitch,
   707                                   const Uint8 *Vplane, int Vpitch);
   708 static int D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
   709                              const SDL_Rect * rect, void **pixels, int *pitch);
   710 static void D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
   711 static int D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
   712 static int D3D11_UpdateViewport(SDL_Renderer * renderer);
   713 static int D3D11_UpdateClipRect(SDL_Renderer * renderer);
   714 static int D3D11_RenderClear(SDL_Renderer * renderer);
   715 static int D3D11_RenderDrawPoints(SDL_Renderer * renderer,
   716                                   const SDL_FPoint * points, int count);
   717 static int D3D11_RenderDrawLines(SDL_Renderer * renderer,
   718                                  const SDL_FPoint * points, int count);
   719 static int D3D11_RenderFillRects(SDL_Renderer * renderer,
   720                                  const SDL_FRect * rects, int count);
   721 static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
   722                             const SDL_Rect * srcrect, const SDL_FRect * dstrect);
   723 static int D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
   724                               const SDL_Rect * srcrect, const SDL_FRect * dstrect,
   725                               const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip);
   726 static int D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
   727                                   Uint32 format, void * pixels, int pitch);
   728 static void D3D11_RenderPresent(SDL_Renderer * renderer);
   729 static void D3D11_DestroyTexture(SDL_Renderer * renderer,
   730                                  SDL_Texture * texture);
   731 static void D3D11_DestroyRenderer(SDL_Renderer * renderer);
   732 
   733 /* Direct3D 11.1 Internal Functions */
   734 static HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer);
   735 static HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer);
   736 static HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer);
   737 static HRESULT D3D11_HandleDeviceLost(SDL_Renderer * renderer);
   738 static void D3D11_ReleaseMainRenderTargetView(SDL_Renderer * renderer);
   739 
   740 SDL_RenderDriver D3D11_RenderDriver = {
   741     D3D11_CreateRenderer,
   742     {
   743         "direct3d11",
   744         (
   745             SDL_RENDERER_ACCELERATED |
   746             SDL_RENDERER_PRESENTVSYNC |
   747             SDL_RENDERER_TARGETTEXTURE
   748         ),                          /* flags.  see SDL_RendererFlags */
   749         4,                          /* num_texture_formats */
   750         {                           /* texture_formats */
   751             SDL_PIXELFORMAT_ARGB8888,
   752             SDL_PIXELFORMAT_RGB888,
   753             SDL_PIXELFORMAT_YV12,
   754             SDL_PIXELFORMAT_IYUV
   755         },
   756         0,                          /* max_texture_width: will be filled in later */
   757         0                           /* max_texture_height: will be filled in later */
   758     }
   759 };
   760 
   761 
   762 static Uint32
   763 DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat) {
   764     switch (dxgiFormat) {
   765         case DXGI_FORMAT_B8G8R8A8_UNORM:
   766             return SDL_PIXELFORMAT_ARGB8888;
   767         case DXGI_FORMAT_B8G8R8X8_UNORM:
   768             return SDL_PIXELFORMAT_RGB888;
   769         default:
   770             return SDL_PIXELFORMAT_UNKNOWN;
   771     }
   772 }
   773 
   774 static DXGI_FORMAT
   775 SDLPixelFormatToDXGIFormat(Uint32 sdlFormat)
   776 {
   777     switch (sdlFormat) {
   778         case SDL_PIXELFORMAT_ARGB8888:
   779             return DXGI_FORMAT_B8G8R8A8_UNORM;
   780         case SDL_PIXELFORMAT_RGB888:
   781             return DXGI_FORMAT_B8G8R8X8_UNORM;
   782         case SDL_PIXELFORMAT_YV12:
   783         case SDL_PIXELFORMAT_IYUV:
   784             return DXGI_FORMAT_R8_UNORM;
   785         default:
   786             return DXGI_FORMAT_UNKNOWN;
   787     }
   788 }
   789 
   790 SDL_Renderer *
   791 D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
   792 {
   793     SDL_Renderer *renderer;
   794     D3D11_RenderData *data;
   795 
   796     renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
   797     if (!renderer) {
   798         SDL_OutOfMemory();
   799         return NULL;
   800     }
   801 
   802     data = (D3D11_RenderData *) SDL_calloc(1, sizeof(*data));
   803     if (!data) {
   804         SDL_OutOfMemory();
   805         return NULL;
   806     }
   807 
   808     renderer->WindowEvent = D3D11_WindowEvent;
   809     renderer->CreateTexture = D3D11_CreateTexture;
   810     renderer->UpdateTexture = D3D11_UpdateTexture;
   811     renderer->UpdateTextureYUV = D3D11_UpdateTextureYUV;
   812     renderer->LockTexture = D3D11_LockTexture;
   813     renderer->UnlockTexture = D3D11_UnlockTexture;
   814     renderer->SetRenderTarget = D3D11_SetRenderTarget;
   815     renderer->UpdateViewport = D3D11_UpdateViewport;
   816     renderer->UpdateClipRect = D3D11_UpdateClipRect;
   817     renderer->RenderClear = D3D11_RenderClear;
   818     renderer->RenderDrawPoints = D3D11_RenderDrawPoints;
   819     renderer->RenderDrawLines = D3D11_RenderDrawLines;
   820     renderer->RenderFillRects = D3D11_RenderFillRects;
   821     renderer->RenderCopy = D3D11_RenderCopy;
   822     renderer->RenderCopyEx = D3D11_RenderCopyEx;
   823     renderer->RenderReadPixels = D3D11_RenderReadPixels;
   824     renderer->RenderPresent = D3D11_RenderPresent;
   825     renderer->DestroyTexture = D3D11_DestroyTexture;
   826     renderer->DestroyRenderer = D3D11_DestroyRenderer;
   827     renderer->info = D3D11_RenderDriver.info;
   828     renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
   829     renderer->driverdata = data;
   830 
   831     if ((flags & SDL_RENDERER_PRESENTVSYNC)) {
   832         renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
   833     }
   834 
   835     /* HACK: make sure the SDL_Renderer references the SDL_Window data now, in
   836      * order to give init functions access to the underlying window handle:
   837      */
   838     renderer->window = window;
   839 
   840     /* Initialize Direct3D resources */
   841     if (FAILED(D3D11_CreateDeviceResources(renderer))) {
   842         D3D11_DestroyRenderer(renderer);
   843         return NULL;
   844     }
   845     if (FAILED(D3D11_CreateWindowSizeDependentResources(renderer))) {
   846         D3D11_DestroyRenderer(renderer);
   847         return NULL;
   848     }
   849 
   850     return renderer;
   851 }
   852 
   853 static void
   854 D3D11_ReleaseAll(SDL_Renderer * renderer)
   855 {
   856     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
   857     SDL_Texture *texture = NULL;
   858 
   859     /* Release all textures */
   860     for (texture = renderer->textures; texture; texture = texture->next) {
   861         D3D11_DestroyTexture(renderer, texture);
   862     }
   863 
   864     /* Release/reset everything else */
   865     if (data) {
   866         SAFE_RELEASE(data->dxgiFactory);
   867         SAFE_RELEASE(data->dxgiAdapter);
   868         SAFE_RELEASE(data->d3dDevice);
   869         SAFE_RELEASE(data->d3dContext);
   870         SAFE_RELEASE(data->swapChain);
   871         SAFE_RELEASE(data->mainRenderTargetView);
   872         SAFE_RELEASE(data->currentOffscreenRenderTargetView);
   873         SAFE_RELEASE(data->inputLayout);
   874         SAFE_RELEASE(data->vertexBuffer);
   875         SAFE_RELEASE(data->vertexShader);
   876         SAFE_RELEASE(data->colorPixelShader);
   877         SAFE_RELEASE(data->texturePixelShader);
   878         SAFE_RELEASE(data->yuvPixelShader);
   879         SAFE_RELEASE(data->blendModeBlend);
   880         SAFE_RELEASE(data->blendModeAdd);
   881         SAFE_RELEASE(data->blendModeMod);
   882         SAFE_RELEASE(data->nearestPixelSampler);
   883         SAFE_RELEASE(data->linearSampler);
   884         SAFE_RELEASE(data->mainRasterizer);
   885         SAFE_RELEASE(data->clippedRasterizer);
   886         SAFE_RELEASE(data->vertexShaderConstants);
   887 
   888         data->swapEffect = (DXGI_SWAP_EFFECT) 0;
   889         data->rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
   890         data->currentRenderTargetView = NULL;
   891         data->currentRasterizerState = NULL;
   892         data->currentBlendState = NULL;
   893         data->currentShader = NULL;
   894         data->currentShaderResource = NULL;
   895         data->currentSampler = NULL;
   896 
   897         /* Unload the D3D libraries.  This should be done last, in order
   898          * to prevent IUnknown::Release() calls from crashing.
   899          */
   900         if (data->hD3D11Mod) {
   901             SDL_UnloadObject(data->hD3D11Mod);
   902             data->hD3D11Mod = NULL;
   903         }
   904         if (data->hDXGIMod) {
   905             SDL_UnloadObject(data->hDXGIMod);
   906             data->hDXGIMod = NULL;
   907         }
   908     }
   909 }
   910 
   911 static void
   912 D3D11_DestroyRenderer(SDL_Renderer * renderer)
   913 {
   914     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
   915     D3D11_ReleaseAll(renderer);
   916     if (data) {
   917         SDL_free(data);
   918     }
   919     SDL_free(renderer);
   920 }
   921 
   922 static HRESULT
   923 D3D11_CreateBlendMode(SDL_Renderer * renderer,
   924                       BOOL enableBlending,
   925                       D3D11_BLEND srcBlend,
   926                       D3D11_BLEND destBlend,
   927                       D3D11_BLEND srcBlendAlpha,
   928                       D3D11_BLEND destBlendAlpha,
   929                       ID3D11BlendState ** blendStateOutput)
   930 {
   931     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
   932     HRESULT result = S_OK;
   933 
   934     D3D11_BLEND_DESC blendDesc;
   935     SDL_zero(blendDesc);
   936     blendDesc.AlphaToCoverageEnable = FALSE;
   937     blendDesc.IndependentBlendEnable = FALSE;
   938     blendDesc.RenderTarget[0].BlendEnable = enableBlending;
   939     blendDesc.RenderTarget[0].SrcBlend = srcBlend;
   940     blendDesc.RenderTarget[0].DestBlend = destBlend;
   941     blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
   942     blendDesc.RenderTarget[0].SrcBlendAlpha = srcBlendAlpha;
   943     blendDesc.RenderTarget[0].DestBlendAlpha = destBlendAlpha;
   944     blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
   945     blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
   946     result = ID3D11Device_CreateBlendState(data->d3dDevice, &blendDesc, blendStateOutput);
   947     if (FAILED(result)) {
   948         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBlendState", result);
   949         return result;
   950     }
   951 
   952     return S_OK;
   953 }
   954 
   955 /* Create resources that depend on the device. */
   956 static HRESULT
   957 D3D11_CreateDeviceResources(SDL_Renderer * renderer)
   958 {
   959     typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory);
   960     PFN_CREATE_DXGI_FACTORY CreateDXGIFactoryFunc;
   961     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
   962     PFN_D3D11_CREATE_DEVICE D3D11CreateDeviceFunc;
   963     IDXGIAdapter *d3dAdapter = NULL;
   964     ID3D11Device *d3dDevice = NULL;
   965     ID3D11DeviceContext *d3dContext = NULL;
   966     IDXGIDevice1 *dxgiDevice = NULL;
   967     HRESULT result = S_OK;
   968     UINT creationFlags;
   969     const char *hint;
   970 
   971     /* This array defines the set of DirectX hardware feature levels this app will support.
   972      * Note the ordering should be preserved.
   973      * Don't forget to declare your application's minimum required feature level in its
   974      * description.  All applications are assumed to support 9.1 unless otherwise stated.
   975      */
   976     D3D_FEATURE_LEVEL featureLevels[] = 
   977     {
   978         D3D_FEATURE_LEVEL_11_1,
   979         D3D_FEATURE_LEVEL_11_0,
   980         D3D_FEATURE_LEVEL_10_1,
   981         D3D_FEATURE_LEVEL_10_0,
   982         D3D_FEATURE_LEVEL_9_3,
   983         D3D_FEATURE_LEVEL_9_2,
   984         D3D_FEATURE_LEVEL_9_1
   985     };
   986 
   987     /* Declare how the input layout for SDL's vertex shader will be setup: */
   988     const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = 
   989     {
   990         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
   991         { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
   992         { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
   993     };
   994 
   995     D3D11_BUFFER_DESC constantBufferDesc;
   996     D3D11_SAMPLER_DESC samplerDesc;
   997     D3D11_RASTERIZER_DESC rasterDesc;
   998 
   999 #ifdef __WINRT__
  1000     CreateDXGIFactoryFunc = CreateDXGIFactory1;
  1001     D3D11CreateDeviceFunc = D3D11CreateDevice;
  1002 #else
  1003     data->hDXGIMod = SDL_LoadObject("dxgi.dll");
  1004     if (!data->hDXGIMod) {
  1005         result = E_FAIL;
  1006         goto done;
  1007     }
  1008 
  1009     CreateDXGIFactoryFunc = (PFN_CREATE_DXGI_FACTORY)SDL_LoadFunction(data->hDXGIMod, "CreateDXGIFactory");
  1010     if (!CreateDXGIFactoryFunc) {
  1011         result = E_FAIL;
  1012         goto done;
  1013     }
  1014 
  1015     data->hD3D11Mod = SDL_LoadObject("d3d11.dll");
  1016     if (!data->hD3D11Mod) {
  1017         result = E_FAIL;
  1018         goto done;
  1019     }
  1020 
  1021     D3D11CreateDeviceFunc = (PFN_D3D11_CREATE_DEVICE)SDL_LoadFunction(data->hD3D11Mod, "D3D11CreateDevice");
  1022     if (!D3D11CreateDeviceFunc) {
  1023         result = E_FAIL;
  1024         goto done;
  1025     }
  1026 #endif /* __WINRT__ */
  1027 
  1028     result = CreateDXGIFactoryFunc(&IID_IDXGIFactory2, &data->dxgiFactory);
  1029     if (FAILED(result)) {
  1030         WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateDXGIFactory", result);
  1031         goto done;
  1032     }
  1033 
  1034     /* FIXME: Should we use the default adapter? */
  1035     result = IDXGIFactory2_EnumAdapters(data->dxgiFactory, 0, &data->dxgiAdapter);
  1036     if (FAILED(result)) {
  1037         WIN_SetErrorFromHRESULT(__FUNCTION__ ", D3D11CreateDevice", result);
  1038         goto done;
  1039     }
  1040 
  1041     /* This flag adds support for surfaces with a different color channel ordering
  1042      * than the API default. It is required for compatibility with Direct2D.
  1043      */
  1044     creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
  1045 
  1046     /* Make sure Direct3D's debugging feature gets used, if the app requests it. */
  1047     hint = SDL_GetHint(SDL_HINT_RENDER_DIRECT3D11_DEBUG);
  1048     if (hint && SDL_atoi(hint) > 0) {
  1049         creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
  1050     }
  1051 
  1052     /* Create the Direct3D 11 API device object and a corresponding context. */
  1053     result = D3D11CreateDeviceFunc(
  1054         data->dxgiAdapter,
  1055         D3D_DRIVER_TYPE_UNKNOWN,
  1056         NULL,
  1057         creationFlags, /* Set set debug and Direct2D compatibility flags. */
  1058         featureLevels, /* List of feature levels this app can support. */
  1059         SDL_arraysize(featureLevels),
  1060         D3D11_SDK_VERSION, /* Always set this to D3D11_SDK_VERSION for Windows Store apps. */
  1061         &d3dDevice, /* Returns the Direct3D device created. */
  1062         &data->featureLevel, /* Returns feature level of device created. */
  1063         &d3dContext /* Returns the device immediate context. */
  1064         );
  1065     if (FAILED(result)) {
  1066         WIN_SetErrorFromHRESULT(__FUNCTION__ ", D3D11CreateDevice", result);
  1067         goto done;
  1068     }
  1069 
  1070     result = ID3D11Device_QueryInterface(d3dDevice, &IID_ID3D11Device1, &data->d3dDevice);
  1071     if (FAILED(result)) {
  1072         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to ID3D11Device1", result);
  1073         goto done;
  1074     }
  1075 
  1076     result = ID3D11DeviceContext_QueryInterface(d3dContext, &IID_ID3D11DeviceContext1, &data->d3dContext);
  1077     if (FAILED(result)) {
  1078         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext to ID3D11DeviceContext1", result);
  1079         goto done;
  1080     }
  1081 
  1082     result = ID3D11Device_QueryInterface(d3dDevice, &IID_IDXGIDevice1, &dxgiDevice);
  1083     if (FAILED(result)) {
  1084         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to IDXGIDevice1", result);
  1085         goto done;
  1086     }
  1087 
  1088     /* Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
  1089      * ensures that the application will only render after each VSync, minimizing power consumption.
  1090      */
  1091     result = IDXGIDevice1_SetMaximumFrameLatency(dxgiDevice, 1);
  1092     if (FAILED(result)) {
  1093         WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIDevice1::SetMaximumFrameLatency", result);
  1094         goto done;
  1095     }
  1096 
  1097     /* Make note of the maximum texture size
  1098      * Max texture sizes are documented on MSDN, at:
  1099      * http://msdn.microsoft.com/en-us/library/windows/apps/ff476876.aspx
  1100      */
  1101     switch (data->featureLevel) {
  1102         case D3D_FEATURE_LEVEL_11_1:
  1103         case D3D_FEATURE_LEVEL_11_0:
  1104             renderer->info.max_texture_width = renderer->info.max_texture_height = 16384;
  1105             break;
  1106 
  1107         case D3D_FEATURE_LEVEL_10_1:
  1108         case D3D_FEATURE_LEVEL_10_0:
  1109             renderer->info.max_texture_width = renderer->info.max_texture_height = 8192;
  1110             break;
  1111 
  1112         case D3D_FEATURE_LEVEL_9_3:
  1113             renderer->info.max_texture_width = renderer->info.max_texture_height = 4096;
  1114             break;
  1115 
  1116         case D3D_FEATURE_LEVEL_9_2:
  1117         case D3D_FEATURE_LEVEL_9_1:
  1118             renderer->info.max_texture_width = renderer->info.max_texture_height = 2048;
  1119             break;
  1120 
  1121         default:
  1122             SDL_SetError(__FUNCTION__ ", Unexpected feature level: %d", data->featureLevel);
  1123             result = E_FAIL;
  1124             goto done;
  1125     }
  1126 
  1127     /* Load in SDL's one and only vertex shader: */
  1128     result = ID3D11Device_CreateVertexShader(data->d3dDevice,
  1129         D3D11_VertexShader,
  1130         sizeof(D3D11_VertexShader),
  1131         NULL,
  1132         &data->vertexShader
  1133         );
  1134     if (FAILED(result)) {
  1135         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateVertexShader", result);
  1136         goto done;
  1137     }
  1138 
  1139     /* Create an input layout for SDL's vertex shader: */
  1140     result = ID3D11Device_CreateInputLayout(data->d3dDevice,
  1141         vertexDesc,
  1142         ARRAYSIZE(vertexDesc),
  1143         D3D11_VertexShader,
  1144         sizeof(D3D11_VertexShader),
  1145         &data->inputLayout
  1146         );
  1147     if (FAILED(result)) {
  1148         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateInputLayout", result);
  1149         goto done;
  1150     }
  1151 
  1152     /* Load in SDL's pixel shaders */
  1153     result = ID3D11Device_CreatePixelShader(data->d3dDevice,
  1154         D3D11_PixelShader_Colors,
  1155         sizeof(D3D11_PixelShader_Colors),
  1156         NULL,
  1157         &data->colorPixelShader
  1158         );
  1159     if (FAILED(result)) {
  1160         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['color' shader]", result);
  1161         goto done;
  1162     }
  1163 
  1164     result = ID3D11Device_CreatePixelShader(data->d3dDevice,
  1165         D3D11_PixelShader_Textures,
  1166         sizeof(D3D11_PixelShader_Textures),
  1167         NULL,
  1168         &data->texturePixelShader
  1169         );
  1170     if (FAILED(result)) {
  1171         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['textures' shader]", result);
  1172         goto done;
  1173     }
  1174 
  1175     result = ID3D11Device_CreatePixelShader(data->d3dDevice,
  1176         D3D11_PixelShader_YUV,
  1177         sizeof(D3D11_PixelShader_YUV),
  1178         NULL,
  1179         &data->yuvPixelShader
  1180         );
  1181     if (FAILED(result)) {
  1182         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['yuv' shader]", result);
  1183         goto done;
  1184     }
  1185 
  1186     /* Setup space to hold vertex shader constants: */
  1187     SDL_zero(constantBufferDesc);
  1188     constantBufferDesc.ByteWidth = sizeof(VertexShaderConstants);
  1189     constantBufferDesc.Usage = D3D11_USAGE_DEFAULT;
  1190     constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
  1191     result = ID3D11Device_CreateBuffer(data->d3dDevice,
  1192         &constantBufferDesc,
  1193         NULL,
  1194         &data->vertexShaderConstants
  1195         );
  1196     if (FAILED(result)) {
  1197         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBuffer [vertex shader constants]", result);
  1198         goto done;
  1199     }
  1200 
  1201     /* Create samplers to use when drawing textures: */
  1202     SDL_zero(samplerDesc);
  1203     samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
  1204     samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
  1205     samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
  1206     samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
  1207     samplerDesc.MipLODBias = 0.0f;
  1208     samplerDesc.MaxAnisotropy = 1;
  1209     samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
  1210     samplerDesc.MinLOD = 0.0f;
  1211     samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
  1212     result = ID3D11Device_CreateSamplerState(data->d3dDevice,
  1213         &samplerDesc,
  1214         &data->nearestPixelSampler
  1215         );
  1216     if (FAILED(result)) {
  1217         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [nearest-pixel filter]", result);
  1218         goto done;
  1219     }
  1220 
  1221     samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
  1222     result = ID3D11Device_CreateSamplerState(data->d3dDevice,
  1223         &samplerDesc,
  1224         &data->linearSampler
  1225         );
  1226     if (FAILED(result)) {
  1227         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [linear filter]", result);
  1228         goto done;
  1229     }
  1230 
  1231     /* Setup Direct3D rasterizer states */
  1232     SDL_zero(rasterDesc);
  1233     rasterDesc.AntialiasedLineEnable = FALSE;
  1234     rasterDesc.CullMode = D3D11_CULL_NONE;
  1235     rasterDesc.DepthBias = 0;
  1236     rasterDesc.DepthBiasClamp = 0.0f;
  1237     rasterDesc.DepthClipEnable = TRUE;
  1238     rasterDesc.FillMode = D3D11_FILL_SOLID;
  1239     rasterDesc.FrontCounterClockwise = FALSE;
  1240     rasterDesc.MultisampleEnable = FALSE;
  1241     rasterDesc.ScissorEnable = FALSE;
  1242     rasterDesc.SlopeScaledDepthBias = 0.0f;
  1243     result = ID3D11Device_CreateRasterizerState(data->d3dDevice, &rasterDesc, &data->mainRasterizer);
  1244     if (FAILED(result)) {
  1245         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState [main rasterizer]", result);
  1246         goto done;
  1247     }
  1248 
  1249     rasterDesc.ScissorEnable = TRUE;
  1250     result = ID3D11Device_CreateRasterizerState(data->d3dDevice, &rasterDesc, &data->clippedRasterizer);
  1251     if (FAILED(result)) {
  1252         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState [clipped rasterizer]", result);
  1253         goto done;
  1254     }
  1255 
  1256     /* Create blending states: */
  1257     result = D3D11_CreateBlendMode(
  1258         renderer,
  1259         TRUE,
  1260         D3D11_BLEND_SRC_ALPHA,          /* srcBlend */
  1261         D3D11_BLEND_INV_SRC_ALPHA,      /* destBlend */
  1262         D3D11_BLEND_ONE,                /* srcBlendAlpha */
  1263         D3D11_BLEND_INV_SRC_ALPHA,      /* destBlendAlpha */
  1264         &data->blendModeBlend);
  1265     if (FAILED(result)) {
  1266         /* D3D11_CreateBlendMode will set the SDL error, if it fails */
  1267         goto done;
  1268     }
  1269 
  1270     result = D3D11_CreateBlendMode(
  1271         renderer,
  1272         TRUE,
  1273         D3D11_BLEND_SRC_ALPHA,          /* srcBlend */
  1274         D3D11_BLEND_ONE,                /* destBlend */
  1275         D3D11_BLEND_ZERO,               /* srcBlendAlpha */
  1276         D3D11_BLEND_ONE,                /* destBlendAlpha */
  1277         &data->blendModeAdd);
  1278     if (FAILED(result)) {
  1279         /* D3D11_CreateBlendMode will set the SDL error, if it fails */
  1280         goto done;
  1281     }
  1282 
  1283     result = D3D11_CreateBlendMode(
  1284         renderer,
  1285         TRUE,
  1286         D3D11_BLEND_ZERO,               /* srcBlend */
  1287         D3D11_BLEND_SRC_COLOR,          /* destBlend */
  1288         D3D11_BLEND_ZERO,               /* srcBlendAlpha */
  1289         D3D11_BLEND_ONE,                /* destBlendAlpha */
  1290         &data->blendModeMod);
  1291     if (FAILED(result)) {
  1292         /* D3D11_CreateBlendMode will set the SDL error, if it fails */
  1293         goto done;
  1294     }
  1295 
  1296     /* Setup render state that doesn't change */
  1297     ID3D11DeviceContext_IASetInputLayout(data->d3dContext, data->inputLayout);
  1298     ID3D11DeviceContext_VSSetShader(data->d3dContext, data->vertexShader, NULL, 0);
  1299     ID3D11DeviceContext_VSSetConstantBuffers(data->d3dContext, 0, 1, &data->vertexShaderConstants);
  1300 
  1301 done:
  1302     SAFE_RELEASE(d3dDevice);
  1303     SAFE_RELEASE(d3dContext);
  1304     SAFE_RELEASE(dxgiDevice);
  1305     return result;
  1306 }
  1307 
  1308 #ifdef __WIN32__
  1309 
  1310 static DXGI_MODE_ROTATION
  1311 D3D11_GetCurrentRotation()
  1312 {
  1313     /* FIXME */
  1314     return DXGI_MODE_ROTATION_IDENTITY;
  1315 }
  1316 
  1317 #endif /* __WIN32__ */
  1318 
  1319 static BOOL
  1320 D3D11_IsDisplayRotated90Degrees(DXGI_MODE_ROTATION rotation)
  1321 {
  1322     switch (rotation) {
  1323         case DXGI_MODE_ROTATION_ROTATE90:
  1324         case DXGI_MODE_ROTATION_ROTATE270:
  1325             return TRUE;
  1326         default:
  1327             return FALSE;
  1328     }
  1329 }
  1330 
  1331 static int
  1332 D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRect, D3D11_RECT * outRect)
  1333 {
  1334     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
  1335     switch (data->rotation) {
  1336         case DXGI_MODE_ROTATION_IDENTITY:
  1337             outRect->left = sdlRect->x;
  1338             outRect->right = sdlRect->x + sdlRect->w;
  1339             outRect->top = sdlRect->y;
  1340             outRect->bottom = sdlRect->y + sdlRect->h;
  1341             break;
  1342         case DXGI_MODE_ROTATION_ROTATE270:
  1343             outRect->left = sdlRect->y;
  1344             outRect->right = sdlRect->y + sdlRect->h;
  1345             outRect->top = renderer->viewport.w - sdlRect->x - sdlRect->w;
  1346             outRect->bottom = renderer->viewport.w - sdlRect->x;
  1347             break;
  1348         case DXGI_MODE_ROTATION_ROTATE180:
  1349             outRect->left = renderer->viewport.w - sdlRect->x - sdlRect->w;
  1350             outRect->right = renderer->viewport.w - sdlRect->x;
  1351             outRect->top = renderer->viewport.h - sdlRect->y - sdlRect->h;
  1352             outRect->bottom = renderer->viewport.h - sdlRect->y;
  1353             break;
  1354         case DXGI_MODE_ROTATION_ROTATE90:
  1355             outRect->left = renderer->viewport.h - sdlRect->y - sdlRect->h;
  1356             outRect->right = renderer->viewport.h - sdlRect->y;
  1357             outRect->top = sdlRect->x;
  1358             outRect->bottom = sdlRect->x + sdlRect->h;
  1359             break;
  1360         default:
  1361             return SDL_SetError("The physical display is in an unknown or unsupported rotation");
  1362     }
  1363     return 0;
  1364 }
  1365 
  1366 static HRESULT
  1367 D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h)
  1368 {
  1369     D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
  1370 #ifdef __WINRT__
  1371     IUnknown *coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer);
  1372     const BOOL usingXAML = (coreWindow == NULL);
  1373 #else
  1374     IUnknown *coreWindow = NULL;
  1375     const BOOL usingXAML = FALSE;
  1376 #endif
  1377     HRESULT result = S_OK;
  1378 
  1379     /* Create a swap chain using the same adapter as the existing Direct3D device. */
  1380     DXGI_SWAP_CHAIN_DESC1 swapChainDesc;
  1381     SDL_zero(swapChainDesc);
  1382     swapChainDesc.Width = w;
  1383     swapChainDesc.Height = h;
  1384     swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; /* This is the most common swap chain format. */
  1385     swapChainDesc.Stereo = FALSE;
  1386     swapChainDesc.SampleDesc.Count = 1; /* Don't use multi-sampling. */
  1387     swapChainDesc.SampleDesc.Quality = 0;
  1388     swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  1389     swapChainDesc.BufferCount = 2; /* Use double-buffering to minimize latency. */
  1390 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
  1391     swapChainDesc.Scaling = DXGI_SCALING_STRETCH; /* On phone, only stretch and aspect-ratio stretch scaling are allowed. */
  1392     swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; /* On phone, no swap effects are supported. */
  1393 #else
  1394     if (usingXAML) {
  1395         swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
  1396     } else {
  1397         swapChainDesc.Scaling = DXGI_SCALING_NONE;
  1398     }
  1399     swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; /* All Windows Store apps must use this SwapEffect. */
  1400 #endif
  1401     swapChainDesc.Flags = 0;
  1402 
  1403     if (coreWindow) {
  1404         result = IDXGIFactory2_CreateSwapChainForCoreWindow(data->dxgiFactory,
  1405             (IUnknown *)data->d3dDevice,
  1406             coreWindow,
  1407             &swapChainDesc,
  1408             NULL, /* Allow on all displays. */
  1409             &data->swapChain
  1410             );
  1411         if (FAILED(result)) {
  1412             WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForCoreWindow", result);
  1413             goto done;
  1414         }
  1415     } else if (usingXAML) {
  1416         result = IDXGIFactory2_CreateSwapChainForComposition(data->dxgiFactory,
  1417             (IUnknown *)data->d3dDevice,
  1418             &swapChainDesc,
  1419             NULL,
  1420             &data->swapChain);
  1421         if (FAILED(result)) {
  1422             WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForComposition", result);
  1423             goto done;
  1424         }
  1425 
  1426 #if WINAPI_FAMILY == WINAPI_FAMILY_APP
  1427         result = ISwapChainBackgroundPanelNative_SetSwapChain(WINRT_GlobalSwapChainBackgroundPanelNative, (IDXGISwapChain *) data->swapChain);
  1428         if (FAILED(result)) {
  1429             WIN_SetErrorFromHRESULT(__FUNCTION__ ", ISwapChainBackgroundPanelNative::SetSwapChain", result);
  1430             goto done;
  1431         }
  1432 #else
  1433         SDL_SetError(__FUNCTION__ ", XAML support is not yet available for Windows Phone");
  1434         result = E_FAIL;
  1435         goto done;
  1436 #endif
  1437     } else {
  1438 #ifdef __WIN32__
  1439         SDL_SysWMinfo windowinfo;
  1440         SDL_VERSION(&windowinfo.version);
  1441         SDL_GetWindowWMInfo(renderer->window, &windowinfo);
  1442 
  1443         result = IDXGIFactory2_CreateSwapChainForHwnd(data->dxgiFactory,
  1444             (IUnknown *)data->d3dDevice,
  1445             windowinfo.info.win.window,
  1446             &swapChainDesc,
  1447             NULL,
  1448             NULL, /* Allow on all displays. */
  1449             &data->swapChain
  1450             );
  1451         if (FAILED(result)) {
  1452             WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForHwnd", result);
  1453             goto done;
  1454         }
  1455 
  1456         IDXGIFactory_MakeWindowAssociation(data->dxgiFactory, windowinfo.info.win.window, DXGI_MWA_NO_WINDOW_CHANGES);
  1457 #else
  1458         SDL_SetError(__FUNCTION__", Unable to find something to attach a swap chain to");
  1459         goto done;
  1460 #endif  /* ifdef __WIN32__ / else */
  1461     }
  1462     data->swapEffect = swapChainDesc.SwapEffect;
  1463 
  1464 done:
  1465     SAFE_RELEASE(coreWindow);
  1466     return result;
  1467 }
  1468 
  1469 
  1470 /* Initialize all resources that change when the window's size changes. */
  1471 static HRESULT
  1472 D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
  1473 {
  1474     D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
  1475     ID3D11Texture2D *backBuffer = NULL;
  1476     HRESULT result = S_OK;
  1477     int w, h;
  1478 
  1479     /* Release the previous render target view */
  1480     D3D11_ReleaseMainRenderTargetView(renderer);
  1481 
  1482     /* The width and height of the swap chain must be based on the display's
  1483      * non-rotated size.
  1484      */
  1485     SDL_GetWindowSize(renderer->window, &w, &h);
  1486     data->rotation = D3D11_GetCurrentRotation();
  1487     if (D3D11_IsDisplayRotated90Degrees(data->rotation)) {
  1488         int tmp = w;
  1489         w = h;
  1490         h = tmp;
  1491     }
  1492 
  1493     if (data->swapChain) {
  1494         /* IDXGISwapChain::ResizeBuffers is not available on Windows Phone 8. */
  1495 #if !defined(__WINRT__) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
  1496         /* If the swap chain already exists, resize it. */
  1497         result = IDXGISwapChain_ResizeBuffers(data->swapChain,
  1498             0,
  1499             w, h,
  1500             DXGI_FORMAT_UNKNOWN,
  1501             0
  1502             );
  1503         if (result == DXGI_ERROR_DEVICE_REMOVED) {
  1504             /* If the device was removed for any reason, a new device and swap chain will need to be created. */
  1505             D3D11_HandleDeviceLost(renderer);
  1506 
  1507             /* Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method 
  1508              * and correctly set up the new device.
  1509              */
  1510             goto done;
  1511         } else if (FAILED(result)) {
  1512             WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain::ResizeBuffers", result);
  1513             goto done;
  1514         }
  1515 #endif
  1516     } else {
  1517         result = D3D11_CreateSwapChain(renderer, w, h);
  1518         if (FAILED(result)) {
  1519             goto done;
  1520         }
  1521     }
  1522     
  1523 #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
  1524     /* Set the proper rotation for the swap chain, and generate the
  1525      * 3D matrix transformation for rendering to the rotated swap chain.
  1526      *
  1527      * To note, the call for this, IDXGISwapChain1::SetRotation, is not necessary
  1528      * on Windows Phone, nor is it supported there.  It's only needed in Windows 8/RT.
  1529      */
  1530     if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) {
  1531         result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation);
  1532         if (FAILED(result)) {
  1533             WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::SetRotation", result);
  1534             goto done;
  1535         }
  1536     }
  1537 #endif
  1538 
  1539     result = IDXGISwapChain_GetBuffer(data->swapChain,
  1540         0,
  1541         &IID_ID3D11Texture2D,
  1542         &backBuffer
  1543         );
  1544     if (FAILED(result)) {
  1545         WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain::GetBuffer [back-buffer]", result);
  1546         goto done;
  1547     }
  1548 
  1549     /* Create a render target view of the swap chain back buffer. */
  1550     result = ID3D11Device_CreateRenderTargetView(data->d3dDevice,
  1551         (ID3D11Resource *)backBuffer,
  1552         NULL,
  1553         &data->mainRenderTargetView
  1554         );
  1555     if (FAILED(result)) {
  1556         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device::CreateRenderTargetView", result);
  1557         goto done;
  1558     }
  1559 
  1560     if (D3D11_UpdateViewport(renderer) != 0) {
  1561         /* D3D11_UpdateViewport will set the SDL error if it fails. */
  1562         result = E_FAIL;
  1563         goto done;
  1564     }
  1565 
  1566 done:
  1567     SAFE_RELEASE(backBuffer);
  1568     return result;
  1569 }
  1570 
  1571 /* This method is called when the window's size changes. */
  1572 static HRESULT
  1573 D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer)
  1574 {
  1575     D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
  1576     return D3D11_CreateWindowSizeDependentResources(renderer);
  1577 }
  1578 
  1579 HRESULT
  1580 D3D11_HandleDeviceLost(SDL_Renderer * renderer)
  1581 {
  1582     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
  1583     HRESULT result = S_OK;
  1584 
  1585     D3D11_ReleaseAll(renderer);
  1586 
  1587     result = D3D11_CreateDeviceResources(renderer);
  1588     if (FAILED(result)) {
  1589         /* D3D11_CreateDeviceResources will set the SDL error */
  1590         return result;
  1591     }
  1592 
  1593     result = D3D11_UpdateForWindowSizeChange(renderer);
  1594     if (FAILED(result)) {
  1595         /* D3D11_UpdateForWindowSizeChange will set the SDL error */
  1596         return result;
  1597     }
  1598 
  1599     /* Let the application know that the device has been reset */
  1600     {
  1601         SDL_Event event;
  1602         event.type = SDL_RENDER_DEVICE_RESET;
  1603         SDL_PushEvent(&event);
  1604     }
  1605 
  1606     return S_OK;
  1607 }
  1608 
  1609 void
  1610 D3D11_Trim(SDL_Renderer * renderer)
  1611 {
  1612 #ifdef __WINRT__
  1613 #if NTDDI_VERSION > NTDDI_WIN8
  1614     D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
  1615     HRESULT result = S_OK;
  1616     IDXGIDevice3 *dxgiDevice = NULL;
  1617 
  1618     result = ID3D11Device_QueryInterface(data->d3dDevice, &IID_IDXGIDevice3, &dxgiDevice);
  1619     if (FAILED(result)) {
  1620         //WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to IDXGIDevice3", result);
  1621         return;
  1622     }
  1623 
  1624     IDXGIDevice3_Trim(dxgiDevice);
  1625     SAFE_RELEASE(dxgiDevice);
  1626 #endif
  1627 #endif
  1628 }
  1629 
  1630 static void
  1631 D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
  1632 {
  1633     if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
  1634         D3D11_UpdateForWindowSizeChange(renderer);
  1635     }
  1636 }
  1637 
  1638 static D3D11_FILTER
  1639 GetScaleQuality(void)
  1640 {
  1641     const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
  1642     if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
  1643         return D3D11_FILTER_MIN_MAG_MIP_POINT;
  1644     } else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ {
  1645         return D3D11_FILTER_MIN_MAG_MIP_LINEAR;
  1646     }
  1647 }
  1648 
  1649 static int
  1650 D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
  1651 {
  1652     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  1653     D3D11_TextureData *textureData;
  1654     HRESULT result;
  1655     DXGI_FORMAT textureFormat = SDLPixelFormatToDXGIFormat(texture->format);
  1656     D3D11_TEXTURE2D_DESC textureDesc;
  1657     D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
  1658 
  1659     if (textureFormat == SDL_PIXELFORMAT_UNKNOWN) {
  1660         return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified",
  1661             __FUNCTION__, texture->format);
  1662     }
  1663 
  1664     textureData = (D3D11_TextureData*) SDL_calloc(1, sizeof(*textureData));
  1665     if (!textureData) {
  1666         SDL_OutOfMemory();
  1667         return -1;
  1668     }
  1669     textureData->scaleMode = GetScaleQuality();
  1670 
  1671     texture->driverdata = textureData;
  1672 
  1673     SDL_zero(textureDesc);
  1674     textureDesc.Width = texture->w;
  1675     textureDesc.Height = texture->h;
  1676     textureDesc.MipLevels = 1;
  1677     textureDesc.ArraySize = 1;
  1678     textureDesc.Format = textureFormat;
  1679     textureDesc.SampleDesc.Count = 1;
  1680     textureDesc.SampleDesc.Quality = 0;
  1681     textureDesc.MiscFlags = 0;
  1682 
  1683     if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
  1684         textureDesc.Usage = D3D11_USAGE_DYNAMIC;
  1685         textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  1686     } else {
  1687         textureDesc.Usage = D3D11_USAGE_DEFAULT;
  1688         textureDesc.CPUAccessFlags = 0;
  1689     }
  1690 
  1691     if (texture->access == SDL_TEXTUREACCESS_TARGET) {
  1692         textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
  1693     } else {
  1694         textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
  1695     }
  1696 
  1697     result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
  1698         &textureDesc,
  1699         NULL,
  1700         &textureData->mainTexture
  1701         );
  1702     if (FAILED(result)) {
  1703         D3D11_DestroyTexture(renderer, texture);
  1704         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D", result);
  1705         return -1;
  1706     }
  1707 
  1708     if (texture->format == SDL_PIXELFORMAT_YV12 ||
  1709         texture->format == SDL_PIXELFORMAT_IYUV) {
  1710         textureData->yuv = SDL_TRUE;
  1711 
  1712         textureDesc.Width /= 2;
  1713         textureDesc.Height /= 2;
  1714 
  1715         result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
  1716             &textureDesc,
  1717             NULL,
  1718             &textureData->mainTextureU
  1719             );
  1720         if (FAILED(result)) {
  1721             D3D11_DestroyTexture(renderer, texture);
  1722             WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D", result);
  1723             return -1;
  1724         }
  1725 
  1726         result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
  1727             &textureDesc,
  1728             NULL,
  1729             &textureData->mainTextureV
  1730             );
  1731         if (FAILED(result)) {
  1732             D3D11_DestroyTexture(renderer, texture);
  1733             WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D", result);
  1734             return -1;
  1735         }
  1736     }
  1737 
  1738     resourceViewDesc.Format = textureDesc.Format;
  1739     resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
  1740     resourceViewDesc.Texture2D.MostDetailedMip = 0;
  1741     resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
  1742     result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
  1743         (ID3D11Resource *)textureData->mainTexture,
  1744         &resourceViewDesc,
  1745         &textureData->mainTextureResourceView
  1746         );
  1747     if (FAILED(result)) {
  1748         D3D11_DestroyTexture(renderer, texture);
  1749         WIN_SetErrorFromHRESULT(__FUNCTION__ "ID3D11Device1::CreateShaderResourceView", result);
  1750         return -1;
  1751     }
  1752 
  1753     if (textureData->yuv) {
  1754         result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
  1755             (ID3D11Resource *)textureData->mainTextureU,
  1756             &resourceViewDesc,
  1757             &textureData->mainTextureResourceViewU
  1758             );
  1759         if (FAILED(result)) {
  1760             D3D11_DestroyTexture(renderer, texture);
  1761             WIN_SetErrorFromHRESULT(__FUNCTION__ "ID3D11Device1::CreateShaderResourceView", result);
  1762             return -1;
  1763         }
  1764         result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
  1765             (ID3D11Resource *)textureData->mainTextureV,
  1766             &resourceViewDesc,
  1767             &textureData->mainTextureResourceViewV
  1768             );
  1769         if (FAILED(result)) {
  1770             D3D11_DestroyTexture(renderer, texture);
  1771             WIN_SetErrorFromHRESULT(__FUNCTION__ "ID3D11Device1::CreateShaderResourceView", result);
  1772             return -1;
  1773         }
  1774     }
  1775 
  1776     if (texture->access & SDL_TEXTUREACCESS_TARGET) {
  1777         D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
  1778         renderTargetViewDesc.Format = textureDesc.Format;
  1779         renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
  1780         renderTargetViewDesc.Texture2D.MipSlice = 0;
  1781 
  1782         result = ID3D11Device_CreateRenderTargetView(rendererData->d3dDevice,
  1783             (ID3D11Resource *)textureData->mainTexture,
  1784             &renderTargetViewDesc,
  1785             &textureData->mainTextureRenderTargetView);
  1786         if (FAILED(result)) {
  1787             D3D11_DestroyTexture(renderer, texture);
  1788             WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRenderTargetView", result);
  1789             return -1;
  1790         }
  1791     }
  1792 
  1793     return 0;
  1794 }
  1795 
  1796 static void
  1797 D3D11_DestroyTexture(SDL_Renderer * renderer,
  1798                      SDL_Texture * texture)
  1799 {
  1800     D3D11_TextureData *data = (D3D11_TextureData *)texture->driverdata;
  1801 
  1802     if (!data) {
  1803         return;
  1804     }
  1805 
  1806     SAFE_RELEASE(data->mainTexture);
  1807     SAFE_RELEASE(data->mainTextureResourceView);
  1808     SAFE_RELEASE(data->mainTextureRenderTargetView);
  1809     SAFE_RELEASE(data->stagingTexture);
  1810     SAFE_RELEASE(data->mainTextureU);
  1811     SAFE_RELEASE(data->mainTextureResourceViewU);
  1812     SAFE_RELEASE(data->mainTextureV);
  1813     SAFE_RELEASE(data->mainTextureResourceViewV);
  1814     SDL_free(data->pixels);
  1815     SDL_free(data);
  1816     texture->driverdata = NULL;
  1817 }
  1818 
  1819 static int
  1820 D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *texture, Uint32 format, int x, int y, int w, int h, const void *pixels, int pitch)
  1821 {
  1822     ID3D11Texture2D *stagingTexture;
  1823     const Uint8 *src;
  1824     Uint8 *dst;
  1825     int row;
  1826     UINT length;
  1827     HRESULT result;
  1828     D3D11_TEXTURE2D_DESC stagingTextureDesc;
  1829     D3D11_MAPPED_SUBRESOURCE textureMemory;
  1830 
  1831     /* Create a 'staging' texture, which will be used to write to a portion of the main texture. */
  1832     ID3D11Texture2D_GetDesc(texture, &stagingTextureDesc);
  1833     stagingTextureDesc.Width = w;
  1834     stagingTextureDesc.Height = h;
  1835     stagingTextureDesc.BindFlags = 0;
  1836     stagingTextureDesc.MiscFlags = 0;
  1837     stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  1838     stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
  1839     result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
  1840         &stagingTextureDesc,
  1841         NULL,
  1842         &stagingTexture);
  1843     if (FAILED(result)) {
  1844         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result);
  1845         return -1;
  1846     }
  1847 
  1848     /* Get a write-only pointer to data in the staging texture: */
  1849     result = ID3D11DeviceContext_Map(rendererData->d3dContext,
  1850         (ID3D11Resource *)stagingTexture,
  1851         0,
  1852         D3D11_MAP_WRITE,
  1853         0,
  1854         &textureMemory
  1855         );
  1856     if (FAILED(result)) {
  1857         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result);
  1858         SAFE_RELEASE(stagingTexture);
  1859         return -1;
  1860     }
  1861 
  1862     src = (const Uint8 *)pixels;
  1863     dst = textureMemory.pData;
  1864     length = w * SDL_BYTESPERPIXEL(format);
  1865     if (length == pitch && length == textureMemory.RowPitch) {
  1866         SDL_memcpy(dst, src, length*h);
  1867     } else {
  1868         if (length > (UINT)pitch) {
  1869             length = pitch;
  1870         }
  1871         if (length > textureMemory.RowPitch) {
  1872             length = textureMemory.RowPitch;
  1873         }
  1874         for (row = 0; row < h; ++row) {
  1875             SDL_memcpy(dst, src, length);
  1876             src += pitch;
  1877             dst += textureMemory.RowPitch;
  1878         }
  1879     }
  1880 
  1881     /* Commit the pixel buffer's changes back to the staging texture: */
  1882     ID3D11DeviceContext_Unmap(rendererData->d3dContext,
  1883         (ID3D11Resource *)stagingTexture,
  1884         0);
  1885 
  1886     /* Copy the staging texture's contents back to the texture: */
  1887     ID3D11DeviceContext_CopySubresourceRegion(rendererData->d3dContext,
  1888         (ID3D11Resource *)texture,
  1889         0,
  1890         x,
  1891         y,
  1892         0,
  1893         (ID3D11Resource *)stagingTexture,
  1894         0,
  1895         NULL);
  1896 
  1897     SAFE_RELEASE(stagingTexture);
  1898 
  1899     return 0;
  1900 }
  1901 
  1902 static int
  1903 D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
  1904                     const SDL_Rect * rect, const void * srcPixels,
  1905                     int srcPitch)
  1906 {
  1907     D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
  1908     D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
  1909 
  1910     if (!textureData) {
  1911         SDL_SetError("Texture is not currently available");
  1912         return -1;
  1913     }
  1914 
  1915     if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, texture->format, rect->x, rect->y, rect->w, rect->h, srcPixels, srcPitch) < 0) {
  1916         return -1;
  1917     }
  1918 
  1919     if (textureData->yuv) {
  1920         /* Skip to the correct offset into the next texture */
  1921         srcPixels = (const void*)((const Uint8*)srcPixels + rect->h * srcPitch);
  1922 
  1923         if (D3D11_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureV : textureData->mainTextureU, texture->format, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, srcPixels, srcPitch / 2) < 0) {
  1924             return -1;
  1925         }
  1926 
  1927         /* Skip to the correct offset into the next texture */
  1928         srcPixels = (const void*)((const Uint8*)srcPixels + (rect->h * srcPitch) / 4);
  1929         if (D3D11_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureU : textureData->mainTextureV, texture->format, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, srcPixels, srcPitch / 2) < 0) {
  1930             return -1;
  1931         }
  1932     }
  1933     return 0;
  1934 }
  1935 
  1936 static int
  1937 D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
  1938                        const SDL_Rect * rect,
  1939                        const Uint8 *Yplane, int Ypitch,
  1940                        const Uint8 *Uplane, int Upitch,
  1941                        const Uint8 *Vplane, int Vpitch)
  1942 {
  1943     D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
  1944     D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
  1945 
  1946     if (!textureData) {
  1947         SDL_SetError("Texture is not currently available");
  1948         return -1;
  1949     }
  1950 
  1951     if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, texture->format, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) {
  1952         return -1;
  1953     }
  1954     if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureU, texture->format, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Uplane, Upitch) < 0) {
  1955         return -1;
  1956     }
  1957     if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureV, texture->format, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Vplane, Vpitch) < 0) {
  1958         return -1;
  1959     }
  1960     return 0;
  1961 }
  1962 
  1963 static int
  1964 D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
  1965                   const SDL_Rect * rect, void **pixels, int *pitch)
  1966 {
  1967     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  1968     D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
  1969     HRESULT result = S_OK;
  1970     D3D11_TEXTURE2D_DESC stagingTextureDesc;
  1971     D3D11_MAPPED_SUBRESOURCE textureMemory;
  1972 
  1973     if (!textureData) {
  1974         SDL_SetError("Texture is not currently available");
  1975         return -1;
  1976     }
  1977 
  1978     if (textureData->yuv) {
  1979         /* It's more efficient to upload directly... */
  1980         if (!textureData->pixels) {
  1981             textureData->pitch = texture->w;
  1982             textureData->pixels = (Uint8 *)SDL_malloc((texture->h * textureData->pitch * 3) / 2);
  1983             if (!textureData->pixels) {
  1984                 return SDL_OutOfMemory();
  1985             }
  1986         }
  1987         textureData->locked_rect = *rect;
  1988         *pixels =
  1989             (void *)((Uint8 *)textureData->pixels + rect->y * textureData->pitch +
  1990             rect->x * SDL_BYTESPERPIXEL(texture->format));
  1991         *pitch = textureData->pitch;
  1992         return 0;
  1993     }
  1994 
  1995     if (textureData->stagingTexture) {
  1996         return SDL_SetError("texture is already locked");
  1997     }
  1998     
  1999     /* Create a 'staging' texture, which will be used to write to a portion
  2000      * of the main texture.  This is necessary, as Direct3D 11.1 does not
  2001      * have the ability to write a CPU-bound pixel buffer to a rectangular
  2002      * subrect of a texture.  Direct3D 11.1 can, however, write a pixel
  2003      * buffer to an entire texture, hence the use of a staging texture.
  2004      *
  2005      * TODO, WinRT: consider avoiding the use of a staging texture in D3D11_LockTexture if/when the entire texture is being updated
  2006      */
  2007     ID3D11Texture2D_GetDesc(textureData->mainTexture, &stagingTextureDesc);
  2008     stagingTextureDesc.Width = rect->w;
  2009     stagingTextureDesc.Height = rect->h;
  2010     stagingTextureDesc.BindFlags = 0;
  2011     stagingTextureDesc.MiscFlags = 0;
  2012     stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  2013     stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
  2014     result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
  2015         &stagingTextureDesc,
  2016         NULL,
  2017         &textureData->stagingTexture);
  2018     if (FAILED(result)) {
  2019         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result);
  2020         return -1;
  2021     }
  2022 
  2023     /* Get a write-only pointer to data in the staging texture: */
  2024     result = ID3D11DeviceContext_Map(rendererData->d3dContext,
  2025         (ID3D11Resource *)textureData->stagingTexture,
  2026         0,
  2027         D3D11_MAP_WRITE,
  2028         0,
  2029         &textureMemory
  2030         );
  2031     if (FAILED(result)) {
  2032         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result);
  2033         SAFE_RELEASE(textureData->stagingTexture);
  2034         return -1;
  2035     }
  2036 
  2037     /* Make note of where the staging texture will be written to 
  2038      * (on a call to SDL_UnlockTexture):
  2039      */
  2040     textureData->lockedTexturePositionX = rect->x;
  2041     textureData->lockedTexturePositionY = rect->y;
  2042 
  2043     /* Make sure the caller has information on the texture's pixel buffer,
  2044      * then return:
  2045      */
  2046     *pixels = textureMemory.pData;
  2047     *pitch = textureMemory.RowPitch;
  2048     return 0;
  2049 }
  2050 
  2051 static void
  2052 D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
  2053 {
  2054     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  2055     D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
  2056     
  2057     if (!textureData) {
  2058         return;
  2059     }
  2060 
  2061     if (textureData->yuv) {
  2062         const SDL_Rect *rect = &textureData->locked_rect;
  2063         void *pixels =
  2064             (void *) ((Uint8 *) textureData->pixels + rect->y * textureData->pitch +
  2065                       rect->x * SDL_BYTESPERPIXEL(texture->format));
  2066         D3D11_UpdateTexture(renderer, texture, rect, pixels, textureData->pitch);
  2067         return;
  2068     }
  2069 
  2070     /* Commit the pixel buffer's changes back to the staging texture: */
  2071     ID3D11DeviceContext_Unmap(rendererData->d3dContext,
  2072         (ID3D11Resource *)textureData->stagingTexture,
  2073         0);
  2074 
  2075     /* Copy the staging texture's contents back to the main texture: */
  2076     ID3D11DeviceContext_CopySubresourceRegion(rendererData->d3dContext,
  2077         (ID3D11Resource *)textureData->mainTexture,
  2078         0,
  2079         textureData->lockedTexturePositionX,
  2080         textureData->lockedTexturePositionY,
  2081         0,
  2082         (ID3D11Resource *)textureData->stagingTexture,
  2083         0,
  2084         NULL);
  2085 
  2086     SAFE_RELEASE(textureData->stagingTexture);
  2087 }
  2088 
  2089 static int
  2090 D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
  2091 {
  2092     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  2093     D3D11_TextureData *textureData = NULL;
  2094 
  2095     if (texture == NULL) {
  2096         rendererData->currentOffscreenRenderTargetView = NULL;
  2097         return 0;
  2098     }
  2099 
  2100     textureData = (D3D11_TextureData *) texture->driverdata;
  2101 
  2102     if (!textureData->mainTextureRenderTargetView) {
  2103         return SDL_SetError("specified texture is not a render target");
  2104     }
  2105 
  2106     rendererData->currentOffscreenRenderTargetView = textureData->mainTextureRenderTargetView;
  2107 
  2108     return 0;
  2109 }
  2110 
  2111 static void
  2112 D3D11_SetModelMatrix(SDL_Renderer *renderer, const Float4X4 *matrix)
  2113 {
  2114     D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
  2115 
  2116     if (matrix) {
  2117         data->vertexShaderConstantsData.model = *matrix;
  2118     } else {
  2119         data->vertexShaderConstantsData.model = MatrixIdentity();
  2120     }
  2121 
  2122     ID3D11DeviceContext_UpdateSubresource(data->d3dContext,
  2123         (ID3D11Resource *)data->vertexShaderConstants,
  2124         0,
  2125         NULL,
  2126         &data->vertexShaderConstantsData,
  2127         0,
  2128         0
  2129         );
  2130 }
  2131 
  2132 static int
  2133 D3D11_UpdateViewport(SDL_Renderer * renderer)
  2134 {
  2135     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
  2136     Float4X4 projection;
  2137     Float4X4 view;
  2138     SDL_FRect orientationAlignedViewport;
  2139     BOOL swapDimensions;
  2140     D3D11_VIEWPORT viewport;
  2141 
  2142     if (renderer->viewport.w == 0 || renderer->viewport.h == 0) {
  2143         /* If the viewport is empty, assume that it is because
  2144          * SDL_CreateRenderer is calling it, and will call it again later
  2145          * with a non-empty viewport.
  2146          */
  2147         return 0;
  2148     }
  2149 
  2150     /* Make sure the SDL viewport gets rotated to that of the physical display's rotation.
  2151      * Keep in mind here that the Y-axis will be been inverted (from Direct3D's
  2152      * default coordinate system) so rotations will be done in the opposite
  2153      * direction of the DXGI_MODE_ROTATION enumeration.
  2154      */
  2155     switch (data->rotation) {
  2156         case DXGI_MODE_ROTATION_IDENTITY:
  2157             projection = MatrixIdentity();
  2158             break;
  2159         case DXGI_MODE_ROTATION_ROTATE270:
  2160             projection = MatrixRotationZ(SDL_static_cast(float, M_PI * 0.5f));
  2161             break;
  2162         case DXGI_MODE_ROTATION_ROTATE180:
  2163             projection = MatrixRotationZ(SDL_static_cast(float, M_PI));
  2164             break;
  2165         case DXGI_MODE_ROTATION_ROTATE90:
  2166             projection = MatrixRotationZ(SDL_static_cast(float, -M_PI * 0.5f));
  2167             break;
  2168         default:
  2169             return SDL_SetError("An unknown DisplayOrientation is being used");
  2170     }
  2171 
  2172     /* Update the view matrix */
  2173     view.m[0][0] = 2.0f / renderer->viewport.w;
  2174     view.m[0][1] = 0.0f;
  2175     view.m[0][2] = 0.0f;
  2176     view.m[0][3] = 0.0f;
  2177     view.m[1][0] = 0.0f;
  2178     view.m[1][1] = -2.0f / renderer->viewport.h;
  2179     view.m[1][2] = 0.0f;
  2180     view.m[1][3] = 0.0f;
  2181     view.m[2][0] = 0.0f;
  2182     view.m[2][1] = 0.0f;
  2183     view.m[2][2] = 1.0f;
  2184     view.m[2][3] = 0.0f;
  2185     view.m[3][0] = -1.0f;
  2186     view.m[3][1] = 1.0f;
  2187     view.m[3][2] = 0.0f;
  2188     view.m[3][3] = 1.0f;
  2189 
  2190     /* Combine the projection + view matrix together now, as both only get
  2191      * set here (as of this writing, on Dec 26, 2013).  When done, store it
  2192      * for eventual transfer to the GPU.
  2193      */
  2194     data->vertexShaderConstantsData.projectionAndView = MatrixMultiply(
  2195             view,
  2196             projection);
  2197 
  2198     /* Reset the model matrix */
  2199     D3D11_SetModelMatrix(renderer, NULL);
  2200 
  2201     /* Update the Direct3D viewport, which seems to be aligned to the
  2202      * swap buffer's coordinate space, which is always in either
  2203      * a landscape mode, for all Windows 8/RT devices, or a portrait mode,
  2204      * for Windows Phone devices.
  2205      */
  2206     swapDimensions = D3D11_IsDisplayRotated90Degrees(data->rotation);
  2207     if (swapDimensions) {
  2208         orientationAlignedViewport.x = (float) renderer->viewport.y;
  2209         orientationAlignedViewport.y = (float) renderer->viewport.x;
  2210         orientationAlignedViewport.w = (float) renderer->viewport.h;
  2211         orientationAlignedViewport.h = (float) renderer->viewport.w;
  2212     } else {
  2213         orientationAlignedViewport.x = (float) renderer->viewport.x;
  2214         orientationAlignedViewport.y = (float) renderer->viewport.y;
  2215         orientationAlignedViewport.w = (float) renderer->viewport.w;
  2216         orientationAlignedViewport.h = (float) renderer->viewport.h;
  2217     }
  2218     /* TODO, WinRT: get custom viewports working with non-Landscape modes (Portrait, PortraitFlipped, and LandscapeFlipped) */
  2219 
  2220     viewport.TopLeftX = orientationAlignedViewport.x;
  2221     viewport.TopLeftY = orientationAlignedViewport.y;
  2222     viewport.Width = orientationAlignedViewport.w;
  2223     viewport.Height = orientationAlignedViewport.h;
  2224     viewport.MinDepth = 0.0f;
  2225     viewport.MaxDepth = 1.0f;
  2226     ID3D11DeviceContext_RSSetViewports(data->d3dContext, 1, &viewport);
  2227 
  2228     return 0;
  2229 }
  2230 
  2231 static int
  2232 D3D11_UpdateClipRect(SDL_Renderer * renderer)
  2233 {
  2234     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
  2235 
  2236     if (!renderer->clipping_enabled) {
  2237         ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 0, NULL);
  2238     } else {
  2239         D3D11_RECT scissorRect;
  2240         if (D3D11_GetViewportAlignedD3DRect(renderer, &renderer->clip_rect, &scissorRect) != 0) {
  2241             /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
  2242             return -1;
  2243         }
  2244         ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 1, &scissorRect);
  2245     }
  2246 
  2247     return 0;
  2248 }
  2249 
  2250 static void
  2251 D3D11_ReleaseMainRenderTargetView(SDL_Renderer * renderer)
  2252 {
  2253     D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
  2254     ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext, 0, NULL, NULL);
  2255     SAFE_RELEASE(data->mainRenderTargetView);
  2256 }
  2257 
  2258 static ID3D11RenderTargetView *
  2259 D3D11_GetCurrentRenderTargetView(SDL_Renderer * renderer)
  2260 {
  2261     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
  2262     if (data->currentOffscreenRenderTargetView) {
  2263         return data->currentOffscreenRenderTargetView;
  2264     } else {
  2265         return data->mainRenderTargetView;
  2266     }
  2267 }
  2268 
  2269 static int
  2270 D3D11_RenderClear(SDL_Renderer * renderer)
  2271 {
  2272     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
  2273     const float colorRGBA[] = {
  2274         (renderer->r / 255.0f),
  2275         (renderer->g / 255.0f),
  2276         (renderer->b / 255.0f),
  2277         (renderer->a / 255.0f)
  2278     };
  2279     ID3D11DeviceContext_ClearRenderTargetView(data->d3dContext,
  2280         D3D11_GetCurrentRenderTargetView(renderer),
  2281         colorRGBA
  2282         );
  2283     return 0;
  2284 }
  2285 
  2286 static int
  2287 D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
  2288                          const void * vertexData, size_t dataSizeInBytes)
  2289 {
  2290     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  2291     D3D11_BUFFER_DESC vertexBufferDesc;
  2292     HRESULT result = S_OK;
  2293     D3D11_SUBRESOURCE_DATA vertexBufferData;
  2294     const UINT stride = sizeof(VertexPositionColor);
  2295     const UINT offset = 0;
  2296 
  2297     if (rendererData->vertexBuffer) {
  2298         ID3D11Buffer_GetDesc(rendererData->vertexBuffer, &vertexBufferDesc);
  2299     } else {
  2300         SDL_zero(vertexBufferDesc);
  2301     }
  2302 
  2303     if (rendererData->vertexBuffer && vertexBufferDesc.ByteWidth >= dataSizeInBytes) {
  2304         D3D11_MAPPED_SUBRESOURCE mappedResource;
  2305         result = ID3D11DeviceContext_Map(rendererData->d3dContext,
  2306             (ID3D11Resource *)rendererData->vertexBuffer,
  2307             0,
  2308             D3D11_MAP_WRITE_DISCARD,
  2309             0,
  2310             &mappedResource
  2311             );
  2312         if (FAILED(result)) {
  2313             WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [vertex buffer]", result);
  2314             return -1;
  2315         }
  2316         SDL_memcpy(mappedResource.pData, vertexData, dataSizeInBytes);
  2317         ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexBuffer, 0);
  2318     } else {
  2319         SAFE_RELEASE(rendererData->vertexBuffer);
  2320 
  2321         vertexBufferDesc.ByteWidth = dataSizeInBytes;
  2322         vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
  2323         vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  2324         vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  2325 
  2326         SDL_zero(vertexBufferData);
  2327         vertexBufferData.pSysMem = vertexData;
  2328         vertexBufferData.SysMemPitch = 0;
  2329         vertexBufferData.SysMemSlicePitch = 0;
  2330 
  2331         result = ID3D11Device_CreateBuffer(rendererData->d3dDevice,
  2332             &vertexBufferDesc,
  2333             &vertexBufferData,
  2334             &rendererData->vertexBuffer
  2335             );
  2336         if (FAILED(result)) {
  2337             WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBuffer [vertex buffer]", result);
  2338             return -1;
  2339         }
  2340 
  2341         ID3D11DeviceContext_IASetVertexBuffers(rendererData->d3dContext,
  2342             0,
  2343             1,
  2344             &rendererData->vertexBuffer,
  2345             &stride,
  2346             &offset
  2347             );
  2348     }
  2349 
  2350     return 0;
  2351 }
  2352 
  2353 static void
  2354 D3D11_RenderStartDrawOp(SDL_Renderer * renderer)
  2355 {
  2356     D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
  2357     ID3D11RasterizerState *rasterizerState;
  2358     ID3D11RenderTargetView *renderTargetView = D3D11_GetCurrentRenderTargetView(renderer);
  2359     if (renderTargetView != rendererData->currentRenderTargetView) {
  2360         ID3D11DeviceContext_OMSetRenderTargets(rendererData->d3dContext,
  2361             1,
  2362             &renderTargetView,
  2363             NULL
  2364             );
  2365         rendererData->currentRenderTargetView = renderTargetView;
  2366     }
  2367 
  2368     if (!renderer->clipping_enabled) {
  2369         rasterizerState = rendererData->mainRasterizer;
  2370     } else {
  2371         rasterizerState = rendererData->clippedRasterizer;
  2372     }
  2373     if (rasterizerState != rendererData->currentRasterizerState) {
  2374         ID3D11DeviceContext_RSSetState(rendererData->d3dContext, rasterizerState);
  2375         rendererData->currentRasterizerState = rasterizerState;
  2376     }
  2377 }
  2378 
  2379 static void
  2380 D3D11_RenderSetBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
  2381 {
  2382     D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
  2383     ID3D11BlendState *blendState = NULL;
  2384     switch (blendMode) {
  2385     case SDL_BLENDMODE_BLEND:
  2386         blendState = rendererData->blendModeBlend;
  2387         break;
  2388     case SDL_BLENDMODE_ADD:
  2389         blendState = rendererData->blendModeAdd;
  2390         break;
  2391     case SDL_BLENDMODE_MOD:
  2392         blendState = rendererData->blendModeMod;
  2393         break;
  2394     case SDL_BLENDMODE_NONE:
  2395         blendState = NULL;
  2396         break;
  2397     }
  2398     if (blendState != rendererData->currentBlendState) {
  2399         ID3D11DeviceContext_OMSetBlendState(rendererData->d3dContext, blendState, 0, 0xFFFFFFFF);
  2400         rendererData->currentBlendState = blendState;
  2401     }
  2402 }
  2403 
  2404 static void
  2405 D3D11_SetPixelShader(SDL_Renderer * renderer,
  2406                      ID3D11PixelShader * shader,
  2407                      int numShaderResources,
  2408                      ID3D11ShaderResourceView ** shaderResources,
  2409                      ID3D11SamplerState * sampler)
  2410 {
  2411     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  2412     ID3D11ShaderResourceView *shaderResource;
  2413     if (shader != rendererData->currentShader) {
  2414         ID3D11DeviceContext_PSSetShader(rendererData->d3dContext, shader, NULL, 0);
  2415         rendererData->currentShader = shader;
  2416     }
  2417     if (numShaderResources > 0) {
  2418         shaderResource = shaderResources[0];
  2419     } else {
  2420         shaderResource = NULL;
  2421     }
  2422     if (shaderResource != rendererData->currentShaderResource) {
  2423         ID3D11DeviceContext_PSSetShaderResources(rendererData->d3dContext, 0, numShaderResources, shaderResources);
  2424         rendererData->currentShaderResource = shaderResource;
  2425     }
  2426     if (sampler != rendererData->currentSampler) {
  2427         ID3D11DeviceContext_PSSetSamplers(rendererData->d3dContext, 0, 1, &sampler);
  2428         rendererData->currentSampler = sampler;
  2429     }
  2430 }
  2431 
  2432 static void
  2433 D3D11_RenderFinishDrawOp(SDL_Renderer * renderer,
  2434                          D3D11_PRIMITIVE_TOPOLOGY primitiveTopology,
  2435                          UINT vertexCount)
  2436 {
  2437     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  2438 
  2439     ID3D11DeviceContext_IASetPrimitiveTopology(rendererData->d3dContext, primitiveTopology);
  2440     ID3D11DeviceContext_Draw(rendererData->d3dContext, vertexCount, 0);
  2441 }
  2442 
  2443 static int
  2444 D3D11_RenderDrawPoints(SDL_Renderer * renderer,
  2445                        const SDL_FPoint * points, int count)
  2446 {
  2447     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  2448     float r, g, b, a;
  2449     VertexPositionColor *vertices;
  2450     int i;
  2451 
  2452     r = (float)(renderer->r / 255.0f);
  2453     g = (float)(renderer->g / 255.0f);
  2454     b = (float)(renderer->b / 255.0f);
  2455     a = (float)(renderer->a / 255.0f);
  2456 
  2457     vertices = SDL_stack_alloc(VertexPositionColor, count);
  2458     for (i = 0; i < min(count, 128); ++i) {
  2459         const VertexPositionColor v = { { points[i].x, points[i].y, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } };
  2460         vertices[i] = v;
  2461     }
  2462 
  2463     D3D11_RenderStartDrawOp(renderer);
  2464     D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
  2465     if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) {
  2466         SDL_stack_free(vertices);
  2467         return -1;
  2468     }
  2469 
  2470     D3D11_SetPixelShader(
  2471         renderer,
  2472         rendererData->colorPixelShader,
  2473         0,
  2474         NULL,
  2475         NULL);
  2476 
  2477     D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, count);
  2478     SDL_stack_free(vertices);
  2479     return 0;
  2480 }
  2481 
  2482 static int
  2483 D3D11_RenderDrawLines(SDL_Renderer * renderer,
  2484                       const SDL_FPoint * points, int count)
  2485 {
  2486     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  2487     float r, g, b, a;
  2488     VertexPositionColor *vertices;
  2489     int i;
  2490 
  2491     r = (float)(renderer->r / 255.0f);
  2492     g = (float)(renderer->g / 255.0f);
  2493     b = (float)(renderer->b / 255.0f);
  2494     a = (float)(renderer->a / 255.0f);
  2495 
  2496     vertices = SDL_stack_alloc(VertexPositionColor, count);
  2497     for (i = 0; i < count; ++i) {
  2498         const VertexPositionColor v = { { points[i].x, points[i].y, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } };
  2499         vertices[i] = v;
  2500     }
  2501 
  2502     D3D11_RenderStartDrawOp(renderer);
  2503     D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
  2504     if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) {
  2505         SDL_stack_free(vertices);
  2506         return -1;
  2507     }
  2508 
  2509     D3D11_SetPixelShader(
  2510         renderer,
  2511         rendererData->colorPixelShader,
  2512         0,
  2513         NULL,
  2514         NULL);
  2515 
  2516     D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, count);
  2517     SDL_stack_free(vertices);
  2518     return 0;
  2519 }
  2520 
  2521 static int
  2522 D3D11_RenderFillRects(SDL_Renderer * renderer,
  2523                       const SDL_FRect * rects, int count)
  2524 {
  2525     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  2526     float r, g, b, a;
  2527     int i;
  2528 
  2529     r = (float)(renderer->r / 255.0f);
  2530     g = (float)(renderer->g / 255.0f);
  2531     b = (float)(renderer->b / 255.0f);
  2532     a = (float)(renderer->a / 255.0f);
  2533 
  2534     for (i = 0; i < count; ++i) {
  2535         VertexPositionColor vertices[] = {
  2536             { { rects[i].x, rects[i].y, 0.0f },                             { 0.0f, 0.0f}, {r, g, b, a} },
  2537             { { rects[i].x, rects[i].y + rects[i].h, 0.0f },                { 0.0f, 0.0f }, { r, g, b, a } },
  2538             { { rects[i].x + rects[i].w, rects[i].y, 0.0f },                { 0.0f, 0.0f }, { r, g, b, a } },
  2539             { { rects[i].x + rects[i].w, rects[i].y + rects[i].h, 0.0f },   { 0.0f, 0.0f }, { r, g, b, a } },
  2540         };
  2541 
  2542         D3D11_RenderStartDrawOp(renderer);
  2543         D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
  2544         if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
  2545             return -1;
  2546         }
  2547 
  2548         D3D11_SetPixelShader(
  2549             renderer,
  2550             rendererData->colorPixelShader,
  2551             0,
  2552             NULL,
  2553             NULL);
  2554 
  2555         D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, SDL_arraysize(vertices));
  2556     }
  2557 
  2558     return 0;
  2559 }
  2560 
  2561 static ID3D11SamplerState *
  2562 D3D11_RenderGetSampler(SDL_Renderer * renderer, SDL_Texture * texture)
  2563 {
  2564     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  2565     D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
  2566 
  2567     switch (textureData->scaleMode) {
  2568     case D3D11_FILTER_MIN_MAG_MIP_POINT:
  2569         return rendererData->nearestPixelSampler;
  2570     case D3D11_FILTER_MIN_MAG_MIP_LINEAR:
  2571         return rendererData->linearSampler;
  2572     default:
  2573         return NULL;
  2574     }
  2575 }
  2576 
  2577 static int
  2578 D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
  2579                  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
  2580 {
  2581     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  2582     D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
  2583     float minu, maxu, minv, maxv;
  2584     Float4 color;
  2585     VertexPositionColor vertices[4];
  2586     ID3D11SamplerState *textureSampler;
  2587 
  2588     D3D11_RenderStartDrawOp(renderer);
  2589     D3D11_RenderSetBlendMode(renderer, texture->blendMode);
  2590 
  2591     minu = (float) srcrect->x / texture->w;
  2592     maxu = (float) (srcrect->x + srcrect->w) / texture->w;
  2593     minv = (float) srcrect->y / texture->h;
  2594     maxv = (float) (srcrect->y + srcrect->h) / texture->h;
  2595 
  2596     color.x = 1.0f;     /* red */
  2597     color.y = 1.0f;     /* green */
  2598     color.z = 1.0f;     /* blue */
  2599     color.w = 1.0f;     /* alpha */
  2600     if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
  2601         color.x = (float)(texture->r / 255.0f);     /* red */
  2602         color.y = (float)(texture->g / 255.0f);     /* green */
  2603         color.z = (float)(texture->b / 255.0f);     /* blue */
  2604     }
  2605     if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
  2606         color.w = (float)(texture->a / 255.0f);     /* alpha */
  2607     }
  2608 
  2609     vertices[0].pos.x = dstrect->x;
  2610     vertices[0].pos.y = dstrect->y;
  2611     vertices[0].pos.z = 0.0f;
  2612     vertices[0].tex.x = minu;
  2613     vertices[0].tex.y = minv;
  2614     vertices[0].color = color;
  2615 
  2616     vertices[1].pos.x = dstrect->x;
  2617     vertices[1].pos.y = dstrect->y + dstrect->h;
  2618     vertices[1].pos.z = 0.0f;
  2619     vertices[1].tex.x = minu;
  2620     vertices[1].tex.y = maxv;
  2621     vertices[1].color = color;
  2622 
  2623     vertices[2].pos.x = dstrect->x + dstrect->w;
  2624     vertices[2].pos.y = dstrect->y;
  2625     vertices[2].pos.z = 0.0f;
  2626     vertices[2].tex.x = maxu;
  2627     vertices[2].tex.y = minv;
  2628     vertices[2].color = color;
  2629 
  2630     vertices[3].pos.x = dstrect->x + dstrect->w;
  2631     vertices[3].pos.y = dstrect->y + dstrect->h;
  2632     vertices[3].pos.z = 0.0f;
  2633     vertices[3].tex.x = maxu;
  2634     vertices[3].tex.y = maxv;
  2635     vertices[3].color = color;
  2636 
  2637     if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
  2638         return -1;
  2639     }
  2640 
  2641     textureSampler = D3D11_RenderGetSampler(renderer, texture);
  2642     if (textureData->yuv) {
  2643         ID3D11ShaderResourceView *shaderResources[] = {
  2644             textureData->mainTextureResourceView,
  2645             textureData->mainTextureResourceViewU,
  2646             textureData->mainTextureResourceViewV
  2647         };
  2648         D3D11_SetPixelShader(
  2649             renderer,
  2650             rendererData->yuvPixelShader,
  2651             SDL_arraysize(shaderResources),
  2652             shaderResources,
  2653             textureSampler);
  2654     } else {
  2655         D3D11_SetPixelShader(
  2656             renderer,
  2657             rendererData->texturePixelShader,
  2658             1,
  2659             &textureData->mainTextureResourceView,
  2660             textureSampler);
  2661     }
  2662 
  2663     D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
  2664 
  2665     return 0;
  2666 }
  2667 
  2668 static int
  2669 D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
  2670                    const SDL_Rect * srcrect, const SDL_FRect * dstrect,
  2671                    const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip)
  2672 {
  2673     D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
  2674     D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
  2675     float minu, maxu, minv, maxv;
  2676     Float4 color;
  2677     Float4X4 modelMatrix;
  2678     float minx, maxx, miny, maxy;
  2679     VertexPositionColor vertices[4];
  2680     ID3D11SamplerState *textureSampler;
  2681 
  2682     D3D11_RenderStartDrawOp(renderer);
  2683     D3D11_RenderSetBlendMode(renderer, texture->blendMode);
  2684 
  2685     minu = (float) srcrect->x / texture->w;
  2686     maxu = (float) (srcrect->x + srcrect->w) / texture->w;
  2687     minv = (float) srcrect->y / texture->h;
  2688     maxv = (float) (srcrect->y + srcrect->h) / texture->h;
  2689 
  2690     color.x = 1.0f;     /* red */
  2691     color.y = 1.0f;     /* green */
  2692     color.z = 1.0f;     /* blue */
  2693     color.w = 1.0f;     /* alpha */
  2694     if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
  2695         color.x = (float)(texture->r / 255.0f);     /* red */
  2696         color.y = (float)(texture->g / 255.0f);     /* green */
  2697         color.z = (float)(texture->b / 255.0f);     /* blue */
  2698     }
  2699     if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
  2700         color.w = (float)(texture->a / 255.0f);     /* alpha */
  2701     }
  2702 
  2703     if (flip & SDL_FLIP_HORIZONTAL) {
  2704         float tmp = maxu;
  2705         maxu = minu;
  2706         minu = tmp;
  2707     }
  2708     if (flip & SDL_FLIP_VERTICAL) {
  2709         float tmp = maxv;
  2710         maxv = minv;
  2711         minv = tmp;
  2712     }
  2713 
  2714     modelMatrix = MatrixMultiply(
  2715             MatrixRotationZ((float)(M_PI * (float) angle / 180.0f)),
  2716             MatrixTranslation(dstrect->x + center->x, dstrect->y + center->y, 0)
  2717             );
  2718     D3D11_SetModelMatrix(renderer, &modelMatrix);
  2719 
  2720     minx = -center->x;
  2721     maxx = dstrect->w - center->x;
  2722     miny = -center->y;
  2723     maxy = dstrect->h - center->y;
  2724 
  2725     vertices[0].pos.x = minx;
  2726     vertices[0].pos.y = miny;
  2727     vertices[0].pos.z = 0.0f;
  2728     vertices[0].tex.x = minu;
  2729     vertices[0].tex.y = minv;
  2730     vertices[0].color = color;
  2731     
  2732     vertices[1].pos.x = minx;
  2733     vertices[1].pos.y = maxy;
  2734     vertices[1].pos.z = 0.0f;
  2735     vertices[1].tex.x = minu;
  2736     vertices[1].tex.y = maxv;
  2737     vertices[1].color = color;
  2738     
  2739     vertices[2].pos.x = maxx;
  2740     vertices[2].pos.y = miny;
  2741     vertices[2].pos.z = 0.0f;
  2742     vertices[2].tex.x = maxu;
  2743     vertices[2].tex.y = minv;
  2744     vertices[2].color = color;
  2745     
  2746     vertices[3].pos.x = maxx;
  2747     vertices[3].pos.y = maxy;
  2748     vertices[3].pos.z = 0.0f;
  2749     vertices[3].tex.x = maxu;
  2750     vertices[3].tex.y = maxv;
  2751     vertices[3].color = color;
  2752 
  2753     if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
  2754         return -1;
  2755     }
  2756 
  2757     textureSampler = D3D11_RenderGetSampler(renderer, texture);
  2758     if (textureData->yuv) {
  2759         ID3D11ShaderResourceView *shaderResources[] = {
  2760             textureData->mainTextureResourceView,
  2761             textureData->mainTextureResourceViewU,
  2762             textureData->mainTextureResourceViewV
  2763         };
  2764         D3D11_SetPixelShader(
  2765             renderer,
  2766             rendererData->yuvPixelShader,
  2767             SDL_arraysize(shaderResources),
  2768             shaderResources,
  2769             textureSampler);
  2770     } else {
  2771         D3D11_SetPixelShader(
  2772             renderer,
  2773             rendererData->texturePixelShader,
  2774             1,
  2775             &textureData->mainTextureResourceView,
  2776             textureSampler);
  2777     }
  2778 
  2779     D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
  2780 
  2781     D3D11_SetModelMatrix(renderer, NULL);
  2782 
  2783     return 0;
  2784 }
  2785 
  2786 static int
  2787 D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
  2788                        Uint32 format, void * pixels, int pitch)
  2789 {
  2790     D3D11_RenderData * data = (D3D11_RenderData *) renderer->driverdata;
  2791     ID3D11Texture2D *backBuffer = NULL;
  2792     ID3D11Texture2D *stagingTexture = NULL;
  2793     HRESULT result;
  2794     int status = -1;
  2795     D3D11_TEXTURE2D_DESC stagingTextureDesc;
  2796     D3D11_RECT srcRect;
  2797     D3D11_BOX srcBox;
  2798     D3D11_MAPPED_SUBRESOURCE textureMemory;
  2799 
  2800     /* Retrieve a pointer to the back buffer: */
  2801     result = IDXGISwapChain_GetBuffer(data->swapChain,
  2802         0,
  2803         &IID_ID3D11Texture2D,
  2804         &backBuffer
  2805         );
  2806     if (FAILED(result)) {
  2807         WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::GetBuffer [get back buffer]", result);
  2808         goto done;
  2809     }
  2810 
  2811     /* Create a staging texture to copy the screen's data to: */
  2812     ID3D11Texture2D_GetDesc(backBuffer, &stagingTextureDesc);
  2813     stagingTextureDesc.Width = rect->w;
  2814     stagingTextureDesc.Height = rect->h;
  2815     stagingTextureDesc.BindFlags = 0;
  2816     stagingTextureDesc.MiscFlags = 0;
  2817     stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
  2818     stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
  2819     result = ID3D11Device_CreateTexture2D(data->d3dDevice,
  2820         &stagingTextureDesc,
  2821         NULL,
  2822         &stagingTexture);
  2823     if (FAILED(result)) {
  2824         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result);
  2825         goto done;
  2826     }
  2827 
  2828     /* Copy the desired portion of the back buffer to the staging texture: */
  2829     if (D3D11_GetViewportAlignedD3DRect(renderer, rect, &srcRect) != 0) {
  2830         /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
  2831         goto done;
  2832     }
  2833 
  2834     srcBox.left = srcRect.left;
  2835     srcBox.right = srcRect.right;
  2836     srcBox.top = srcRect.top;
  2837     srcBox.bottom = srcRect.bottom;
  2838     srcBox.front = 0;
  2839     srcBox.back = 1;
  2840     ID3D11DeviceContext_CopySubresourceRegion(data->d3dContext,
  2841         (ID3D11Resource *)stagingTexture,
  2842         0,
  2843         0, 0, 0,
  2844         (ID3D11Resource *)backBuffer,
  2845         0,
  2846         &srcBox);
  2847 
  2848     /* Map the staging texture's data to CPU-accessible memory: */
  2849     result = ID3D11DeviceContext_Map(data->d3dContext,
  2850         (ID3D11Resource *)stagingTexture,
  2851         0,
  2852         D3D11_MAP_READ,
  2853         0,
  2854         &textureMemory);
  2855     if (FAILED(result)) {
  2856         WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result);
  2857         goto done;
  2858     }
  2859 
  2860     /* Copy the data into the desired buffer, converting pixels to the
  2861      * desired format at the same time:
  2862      */
  2863     if (SDL_ConvertPixels(
  2864         rect->w, rect->h,
  2865         DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format),
  2866         textureMemory.pData,
  2867         textureMemory.RowPitch,
  2868         format,
  2869         pixels,
  2870         pitch) != 0) {
  2871         /* When SDL_ConvertPixels fails, it'll have already set the format.
  2872          * Get the error message, and attach some extra data to it.
  2873          */
  2874         char errorMessage[1024];
  2875         SDL_snprintf(errorMessage, sizeof(errorMessage), __FUNCTION__ ", Convert Pixels failed: %s", SDL_GetError());
  2876         SDL_SetError(errorMessage);
  2877         goto done;
  2878     }
  2879 
  2880     /* Unmap the texture: */
  2881     ID3D11DeviceContext_Unmap(data->d3dContext,
  2882         (ID3D11Resource *)stagingTexture,
  2883         0);
  2884 
  2885     status = 0;
  2886 
  2887 done:
  2888     SAFE_RELEASE(backBuffer);
  2889     SAFE_RELEASE(stagingTexture);
  2890     return status;
  2891 }
  2892 
  2893 static void
  2894 D3D11_RenderPresent(SDL_Renderer * renderer)
  2895 {
  2896     D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
  2897     UINT syncInterval;
  2898     UINT presentFlags;
  2899     HRESULT result;
  2900     DXGI_PRESENT_PARAMETERS parameters;
  2901 
  2902     SDL_zero(parameters);
  2903 
  2904 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
  2905     syncInterval = 1;
  2906     presentFlags = 0;
  2907     result = IDXGISwapChain_Present(data->swapChain, syncInterval, presentFlags);
  2908 #else
  2909     if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
  2910         syncInterval = 1;
  2911         presentFlags = 0;
  2912     } else {
  2913         syncInterval = 0;
  2914         presentFlags = DXGI_PRESENT_DO_NOT_WAIT;
  2915     }
  2916 
  2917     /* The application may optionally specify "dirty" or "scroll"
  2918      * rects to improve efficiency in certain scenarios.
  2919      * This option is not available on Windows Phone 8, to note.
  2920      */
  2921     result = IDXGISwapChain1_Present1(data->swapChain, syncInterval, presentFlags, &parameters);
  2922 #endif
  2923 
  2924     /* Discard the contents of the render target.
  2925      * This is a valid operation only when the existing contents will be entirely
  2926      * overwritten. If dirty or scroll rects are used, this call should be removed.
  2927      */
  2928     ID3D11DeviceContext1_DiscardView(data->d3dContext, (ID3D11View*)data->mainRenderTargetView);
  2929 
  2930     /* When the present flips, it unbinds the current view, so bind it again on the next draw call */
  2931     data->currentRenderTargetView = NULL;
  2932 
  2933     if (FAILED(result) && result != DXGI_ERROR_WAS_STILL_DRAWING) {
  2934         /* If the device was removed either by a disconnect or a driver upgrade, we 
  2935          * must recreate all device resources.
  2936          *
  2937          * TODO, WinRT: consider throwing an exception if D3D11_RenderPresent fails, especially if there is a way to salvage debug info from users' machines
  2938          */
  2939         if ( result == DXGI_ERROR_DEVICE_REMOVED ) {
  2940             D3D11_HandleDeviceLost(renderer);
  2941         } else if (result == DXGI_ERROR_INVALID_CALL) {
  2942             /* We probably went through a fullscreen <-> windowed transition */
  2943             D3D11_CreateWindowSizeDependentResources(renderer);
  2944         } else {
  2945             WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain::Present", result);
  2946         }
  2947     }
  2948 }
  2949 
  2950 #endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */
  2951 
  2952 /* vi: set ts=4 sw=4 expandtab: */