cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_render_d3d11.c (119034B)


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