src/render/direct3d11/SDL_render_d3d11.c
author David Ludwig <dludwig@pobox.com>
Mon, 10 Mar 2014 22:53:03 -0400
changeset 8607 ef23c9d08eed
parent 8599 532cd234e923
child 8608 c5d603f7094e
permissions -rw-r--r--
Made VS2012 build the D3D11 renderer

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