src/render/direct3d11/SDL_render_d3d11.c
author David Ludwig
Sun, 08 Feb 2015 15:44:15 -0500
changeset 9335 3eb0896ecb91
parent 9158 8fa5ff95c410
child 9549 9ee07b0b24f6
permissions -rw-r--r--
WinRT: made note that VSync is always enabled on WinPhone, due to OS

Windows Phone does not appear to allow VSync to be turned off. Doing so appears
to either result in content not getting drawn (when the D3D debug runtime is
turned off), or forcing VSync back on and logging an error (when the D3D debug
runtime is turned on).

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