src/render/direct3d11/SDL_render_d3d11.cpp
author David Ludwig <dludwig@pobox.com>
Wed, 25 Dec 2013 21:39:48 -0500
changeset 8563 c0e68f3b6bbb
parent 8561 c10e5bfa6459
child 8564 03366aeff6c6
permissions -rw-r--r--
WinRT: compiled the d3d11 renderer's shaders into SDL itself

Previously, the shaders would get compiled separately, the output of which would need to be packaged into the app. This change should make SDL's dll be the only binary needed to include SDL in a WinRT app.
dludwig@8400
     1
/*
dludwig@8400
     2
  Simple DirectMedia Layer
dludwig@8400
     3
  Copyright (C) 1997-2012 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
*/
dludwig@8400
    21
dludwig@8400
    22
#include "SDL_config.h"
dludwig@8400
    23
dludwig@8400
    24
#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
dludwig@8400
    25
dludwig@8463
    26
#ifdef __WINRT__
dludwig@8463
    27
#include <windows.ui.core.h>
dludwig@8463
    28
#include <windows.foundation.h>
dludwig@8505
    29
dludwig@8505
    30
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
dludwig@8505
    31
#include <windows.ui.xaml.media.dxinterop.h>
dludwig@8505
    32
#endif
dludwig@8505
    33
dludwig@8463
    34
#endif
dludwig@8463
    35
dludwig@8400
    36
extern "C" {
dludwig@8400
    37
#include "../../core/windows/SDL_windows.h"
dludwig@8533
    38
#include "SDL_hints.h"
dludwig@8400
    39
//#include "SDL_loadso.h"
dludwig@8410
    40
#include "SDL_system.h"
dludwig@8400
    41
#include "SDL_syswm.h"
dludwig@8400
    42
#include "../SDL_sysrender.h"
dludwig@8433
    43
#include "SDL_log.h"
dludwig@8433
    44
#include "../../video/SDL_sysvideo.h"
dludwig@8400
    45
//#include "stdio.h"
dludwig@8400
    46
}
dludwig@8400
    47
dludwig@8410
    48
#include <fstream>
dludwig@8410
    49
#include <string>
dludwig@8410
    50
#include <vector>
dludwig@8410
    51
dludwig@8559
    52
#include <D3D11_1.h>
dludwig@8559
    53
#include <DirectXMath.h>
dludwig@8559
    54
#include <wrl/client.h>
dludwig@8559
    55
dludwig@8400
    56
dludwig@8410
    57
using namespace DirectX;
dludwig@8410
    58
using namespace Microsoft::WRL;
dludwig@8410
    59
using namespace std;
dludwig@8410
    60
dludwig@8412
    61
#ifdef __WINRT__
dludwig@8412
    62
using namespace Windows::Graphics::Display;
dludwig@8412
    63
using namespace Windows::UI::Core;
dludwig@8412
    64
#endif
dludwig@8412
    65
dludwig@8540
    66
/* Texture sampling types */
dludwig@8540
    67
static const D3D11_FILTER SDL_D3D11_NEAREST_PIXEL_FILTER = D3D11_FILTER_MIN_MAG_MIP_POINT;
dludwig@8540
    68
static const D3D11_FILTER SDL_D3D11_LINEAR_FILTER = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
dludwig@8540
    69
dludwig@8559
    70
/* Vertex shader, common values */
dludwig@8560
    71
struct VertexShaderConstants
dludwig@8559
    72
{
dludwig@8559
    73
    DirectX::XMFLOAT4X4 model;
dludwig@8559
    74
    DirectX::XMFLOAT4X4 view;
dludwig@8559
    75
    DirectX::XMFLOAT4X4 projection;
dludwig@8559
    76
};
dludwig@8559
    77
dludwig@8559
    78
/* Per-vertex data */
dludwig@8559
    79
struct VertexPositionColor
dludwig@8559
    80
{
dludwig@8559
    81
    DirectX::XMFLOAT3 pos;
dludwig@8559
    82
    DirectX::XMFLOAT2 tex;
dludwig@8559
    83
    DirectX::XMFLOAT4 color;
dludwig@8559
    84
};
dludwig@8559
    85
dludwig@8559
    86
/* Per-texture data */
dludwig@8559
    87
typedef struct
dludwig@8559
    88
{
dludwig@8559
    89
    Microsoft::WRL::ComPtr<ID3D11Texture2D> mainTexture;
dludwig@8559
    90
    Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> mainTextureResourceView;
dludwig@8559
    91
    Microsoft::WRL::ComPtr<ID3D11RenderTargetView> mainTextureRenderTargetView;
dludwig@8559
    92
    SDL_PixelFormat * pixelFormat;
dludwig@8559
    93
    Microsoft::WRL::ComPtr<ID3D11Texture2D> stagingTexture;
dludwig@8559
    94
    DirectX::XMINT2 lockedTexturePosition;
dludwig@8559
    95
    D3D11_FILTER scaleMode;
dludwig@8559
    96
} D3D11_TextureData;
dludwig@8559
    97
dludwig@8559
    98
/* Private renderer data */
dludwig@8559
    99
typedef struct
dludwig@8559
   100
{
dludwig@8559
   101
    Microsoft::WRL::ComPtr<ID3D11Device1> d3dDevice;
dludwig@8559
   102
    Microsoft::WRL::ComPtr<ID3D11DeviceContext1> d3dContext;
dludwig@8559
   103
    Microsoft::WRL::ComPtr<IDXGISwapChain1> swapChain;
dludwig@8559
   104
    Microsoft::WRL::ComPtr<ID3D11RenderTargetView> mainRenderTargetView;
dludwig@8559
   105
    Microsoft::WRL::ComPtr<ID3D11RenderTargetView> currentOffscreenRenderTargetView;
dludwig@8559
   106
    Microsoft::WRL::ComPtr<ID3D11InputLayout> inputLayout;
dludwig@8559
   107
    Microsoft::WRL::ComPtr<ID3D11Buffer> vertexBuffer;
dludwig@8559
   108
    Microsoft::WRL::ComPtr<ID3D11VertexShader> vertexShader;
dludwig@8559
   109
    Microsoft::WRL::ComPtr<ID3D11PixelShader> texturePixelShader;
dludwig@8559
   110
    Microsoft::WRL::ComPtr<ID3D11PixelShader> colorPixelShader;
dludwig@8559
   111
    Microsoft::WRL::ComPtr<ID3D11BlendState> blendModeBlend;
dludwig@8559
   112
    Microsoft::WRL::ComPtr<ID3D11BlendState> blendModeAdd;
dludwig@8559
   113
    Microsoft::WRL::ComPtr<ID3D11BlendState> blendModeMod;
dludwig@8559
   114
    Microsoft::WRL::ComPtr<ID3D11SamplerState> nearestPixelSampler;
dludwig@8559
   115
    Microsoft::WRL::ComPtr<ID3D11SamplerState> linearSampler;
dludwig@8559
   116
    Microsoft::WRL::ComPtr<ID3D11RasterizerState> mainRasterizer;
dludwig@8559
   117
    D3D_FEATURE_LEVEL featureLevel;
dludwig@8559
   118
dludwig@8559
   119
    // Vertex buffer constants:
dludwig@8560
   120
    VertexShaderConstants vertexShaderConstantsData;
dludwig@8559
   121
    Microsoft::WRL::ComPtr<ID3D11Buffer> vertexShaderConstants;
dludwig@8559
   122
dludwig@8559
   123
    // Cached renderer properties.
dludwig@8559
   124
    DirectX::XMFLOAT2 windowSizeInDIPs;
dludwig@8559
   125
    DirectX::XMFLOAT2 renderTargetSize;
dludwig@8559
   126
    Windows::Graphics::Display::DisplayOrientations orientation;
dludwig@8559
   127
dludwig@8559
   128
    // Transform used for display orientation.
dludwig@8559
   129
    DirectX::XMFLOAT4X4 orientationTransform3D;
dludwig@8559
   130
} D3D11_RenderData;
dludwig@8559
   131
dludwig@8559
   132
dludwig@8563
   133
/* Direct3D 11.x shaders
dludwig@8563
   134
dludwig@8563
   135
   SDL's shaders are compiled into SDL itself, to simplify distribution.
dludwig@8563
   136
dludwig@8563
   137
   All Direct3D 11.x shaders were compiled with the following:
dludwig@8563
   138
dludwig@8563
   139
   fxc /E"main" /T "<TYPE>" /Fo"<OUTPUT FILE>" "<INPUT FILE>"
dludwig@8563
   140
dludwig@8563
   141
     Variables:
dludwig@8563
   142
     - <TYPE>: the type of shader.  A table of utilized shader types is
dludwig@8563
   143
       listed below.
dludwig@8563
   144
     - <OUTPUT FILE>: where to store compiled output
dludwig@8563
   145
     - <INPUT FILE>: where to read shader source code from
dludwig@8563
   146
dludwig@8563
   147
     Shader types:
dludwig@8563
   148
     - ps_4_0_level_9_1: Pixel shader for Windows 8+, including Windows RT
dludwig@8563
   149
     - vs_4_0_level_9_1: Vertex shader for Windows 8+, including Windows RT
dludwig@8563
   150
     - ps_4_0_level_9_3: Pixel shader for Windows Phone 8
dludwig@8563
   151
     - vs_4_0_level_9_3: Vertex shader for Windows Phone 8
dludwig@8563
   152
  */
dludwig@8563
   153
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
dludwig@8563
   154
#define D3D11_USE_SHADER_MODEL_4_0_level_9_3
dludwig@8563
   155
#else
dludwig@8563
   156
#define D3D11_USE_SHADER_MODEL_4_0_level_9_1
dludwig@8563
   157
#endif
dludwig@8563
   158
dludwig@8563
   159
/* The texture-rendering pixel shader:
dludwig@8563
   160
dludwig@8563
   161
    --- D3D11_PixelShader_Textures.hlsl ---
dludwig@8563
   162
    Texture2D theTexture : register(t0);
dludwig@8563
   163
    SamplerState theSampler : register(s0);
dludwig@8563
   164
dludwig@8563
   165
    struct PixelShaderInput
dludwig@8563
   166
    {
dludwig@8563
   167
        float4 pos : SV_POSITION;
dludwig@8563
   168
        float2 tex : TEXCOORD0;
dludwig@8563
   169
        float4 color : COLOR0;
dludwig@8563
   170
    };
dludwig@8563
   171
dludwig@8563
   172
    float4 main(PixelShaderInput input) : SV_TARGET
dludwig@8563
   173
    {
dludwig@8563
   174
        return theTexture.Sample(theSampler, input.tex) * input.color;
dludwig@8563
   175
    }
dludwig@8563
   176
*/
dludwig@8563
   177
#if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
dludwig@8563
   178
static const DWORD D3D11_PixelShader_Textures[] = {
dludwig@8563
   179
    0x43425844, 0x6299b59f, 0x155258f2, 0x873ab86a, 0xfcbb6dcd, 0x00000001,
dludwig@8563
   180
    0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8,
dludwig@8563
   181
    0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200,
dludwig@8563
   182
    0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001,
dludwig@8563
   183
    0x00280000, 0x00000000, 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000,
dludwig@8563
   184
    0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800,
dludwig@8563
   185
    0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000,
dludwig@8563
   186
    0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff,
dludwig@8563
   187
    0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000,
dludwig@8563
   188
    0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062,
dludwig@8563
   189
    0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065,
dludwig@8563
   190
    0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2,
dludwig@8563
   191
    0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000,
dludwig@8563
   192
    0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
dludwig@8563
   193
    0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003,
dludwig@8563
   194
    0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000,
dludwig@8563
   195
    0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   196
    0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   197
    0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   198
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8,
dludwig@8563
   199
    0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100,
dludwig@8563
   200
    0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   201
    0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005,
dludwig@8563
   202
    0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874,
dludwig@8563
   203
    0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263,
dludwig@8563
   204
    0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43,
dludwig@8563
   205
    0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00,
dludwig@8563
   206
    0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
dludwig@8563
   207
    0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
dludwig@8563
   208
    0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000,
dludwig@8563
   209
    0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
dludwig@8563
   210
    0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
dludwig@8563
   211
    0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
dludwig@8563
   212
    0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
dludwig@8563
   213
};
dludwig@8563
   214
#elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
dludwig@8563
   215
static const DWORD D3D11_PixelShader_Textures[] = {
dludwig@8563
   216
    0x43425844, 0x5876569a, 0x01b6c87e, 0x8447454f, 0xc7f3ef10, 0x00000001,
dludwig@8563
   217
    0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8,
dludwig@8563
   218
    0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200,
dludwig@8563
   219
    0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001,
dludwig@8563
   220
    0x00280000, 0x00000000, 0xffff0201, 0x0200001f, 0x80000000, 0xb0030000,
dludwig@8563
   221
    0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800,
dludwig@8563
   222
    0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000,
dludwig@8563
   223
    0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff,
dludwig@8563
   224
    0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000,
dludwig@8563
   225
    0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062,
dludwig@8563
   226
    0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065,
dludwig@8563
   227
    0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2,
dludwig@8563
   228
    0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000,
dludwig@8563
   229
    0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
dludwig@8563
   230
    0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003,
dludwig@8563
   231
    0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000,
dludwig@8563
   232
    0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   233
    0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   234
    0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   235
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8,
dludwig@8563
   236
    0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100,
dludwig@8563
   237
    0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   238
    0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005,
dludwig@8563
   239
    0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874,
dludwig@8563
   240
    0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263,
dludwig@8563
   241
    0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43,
dludwig@8563
   242
    0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00,
dludwig@8563
   243
    0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
dludwig@8563
   244
    0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
dludwig@8563
   245
    0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000,
dludwig@8563
   246
    0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
dludwig@8563
   247
    0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
dludwig@8563
   248
    0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
dludwig@8563
   249
    0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
dludwig@8563
   250
};
dludwig@8563
   251
#else
dludwig@8563
   252
#error "An appropriate 'textures' pixel shader is not defined"
dludwig@8563
   253
#endif
dludwig@8563
   254
dludwig@8563
   255
/* The color-only-rendering pixel shader:
dludwig@8563
   256
dludwig@8563
   257
   --- D3D11_PixelShader_Colors.hlsl ---
dludwig@8563
   258
   struct PixelShaderInput
dludwig@8563
   259
   {
dludwig@8563
   260
       float4 pos : SV_POSITION;
dludwig@8563
   261
       float2 tex : TEXCOORD0;
dludwig@8563
   262
       float4 color : COLOR0;
dludwig@8563
   263
   };
dludwig@8563
   264
dludwig@8563
   265
   float4 main(PixelShaderInput input) : SV_TARGET
dludwig@8563
   266
   {
dludwig@8563
   267
       return input.color;
dludwig@8563
   268
   }
dludwig@8563
   269
*/
dludwig@8563
   270
#if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
dludwig@8563
   271
static const DWORD D3D11_PixelShader_Colors[] = {
dludwig@8563
   272
    0x43425844, 0xd74c28fe, 0xa1eb8804, 0x269d512a, 0x7699723d, 0x00000001,
dludwig@8563
   273
    0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140,
dludwig@8563
   274
    0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200,
dludwig@8563
   275
    0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000,
dludwig@8563
   276
    0x00240000, 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001,
dludwig@8563
   277
    0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040,
dludwig@8563
   278
    0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2,
dludwig@8563
   279
    0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002,
dludwig@8563
   280
    0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000,
dludwig@8563
   281
    0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
dludwig@8563
   282
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   283
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000,
dludwig@8563
   284
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   285
    0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000,
dludwig@8563
   286
    0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d,
dludwig@8563
   287
    0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072,
dludwig@8563
   288
    0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438,
dludwig@8563
   289
    0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
dludwig@8563
   290
    0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
dludwig@8563
   291
    0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000,
dludwig@8563
   292
    0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
dludwig@8563
   293
    0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
dludwig@8563
   294
    0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
dludwig@8563
   295
    0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
dludwig@8563
   296
};
dludwig@8563
   297
#elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
dludwig@8563
   298
static const DWORD D3D11_PixelShader_Colors[] = {
dludwig@8563
   299
    0x43425844, 0x93f6ccfc, 0x5f919270, 0x7a11aa4f, 0x9148e931, 0x00000001,
dludwig@8563
   300
    0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140,
dludwig@8563
   301
    0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200,
dludwig@8563
   302
    0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000,
dludwig@8563
   303
    0x00240000, 0xffff0201, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001,
dludwig@8563
   304
    0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040,
dludwig@8563
   305
    0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2,
dludwig@8563
   306
    0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002,
dludwig@8563
   307
    0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000,
dludwig@8563
   308
    0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
dludwig@8563
   309
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   310
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000,
dludwig@8563
   311
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   312
    0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000,
dludwig@8563
   313
    0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d,
dludwig@8563
   314
    0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072,
dludwig@8563
   315
    0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438,
dludwig@8563
   316
    0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
dludwig@8563
   317
    0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
dludwig@8563
   318
    0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000,
dludwig@8563
   319
    0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
dludwig@8563
   320
    0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
dludwig@8563
   321
    0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
dludwig@8563
   322
    0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054,
dludwig@8563
   323
};
dludwig@8563
   324
#else
dludwig@8563
   325
#error "An appropriate 'colors' pixel shader is not defined."
dludwig@8563
   326
#endif
dludwig@8563
   327
dludwig@8563
   328
/* The sole vertex shader:
dludwig@8563
   329
dludwig@8563
   330
   --- D3D11_VertexShader.hlsl ---
dludwig@8563
   331
   #pragma pack_matrix( row_major )
dludwig@8563
   332
dludwig@8563
   333
   cbuffer VertexShaderConstants : register(b0)
dludwig@8563
   334
   {
dludwig@8563
   335
       matrix model;
dludwig@8563
   336
       matrix view;
dludwig@8563
   337
       matrix projection;
dludwig@8563
   338
   };
dludwig@8563
   339
dludwig@8563
   340
   struct VertexShaderInput
dludwig@8563
   341
   {
dludwig@8563
   342
       float3 pos : POSITION;
dludwig@8563
   343
       float2 tex : TEXCOORD0;
dludwig@8563
   344
       float4 color : COLOR0;
dludwig@8563
   345
   };
dludwig@8563
   346
dludwig@8563
   347
   struct VertexShaderOutput
dludwig@8563
   348
   {
dludwig@8563
   349
       float4 pos : SV_POSITION;
dludwig@8563
   350
       float2 tex : TEXCOORD0;
dludwig@8563
   351
       float4 color : COLOR0;
dludwig@8563
   352
   };
dludwig@8563
   353
dludwig@8563
   354
   VertexShaderOutput main(VertexShaderInput input)
dludwig@8563
   355
   {
dludwig@8563
   356
       VertexShaderOutput output;
dludwig@8563
   357
       float4 pos = float4(input.pos, 1.0f);
dludwig@8563
   358
dludwig@8563
   359
       // Transform the vertex position into projected space.
dludwig@8563
   360
       pos = mul(pos, model);
dludwig@8563
   361
       pos = mul(pos, view);
dludwig@8563
   362
       pos = mul(pos, projection);
dludwig@8563
   363
       output.pos = pos;
dludwig@8563
   364
dludwig@8563
   365
       // Pass through texture coordinates and color values without transformation
dludwig@8563
   366
       output.tex = input.tex;
dludwig@8563
   367
       output.color = input.color;
dludwig@8563
   368
dludwig@8563
   369
       return output;
dludwig@8563
   370
   }
dludwig@8563
   371
*/
dludwig@8563
   372
#if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
dludwig@8563
   373
static const DWORD D3D11_VertexShader[] = {
dludwig@8563
   374
    0x43425844, 0x3f31b022, 0x2ffad8b8, 0xd6c45cbd, 0xa7894c28, 0x00000001,
dludwig@8563
   375
    0x00000690, 0x00000006, 0x00000038, 0x000001b8, 0x00000418, 0x00000494,
dludwig@8563
   376
    0x000005ac, 0x0000061c, 0x396e6f41, 0x00000178, 0x00000178, 0xfffe0200,
dludwig@8563
   377
    0x00000144, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000,
dludwig@8563
   378
    0x00300001, 0x00000000, 0x0001000c, 0x00000000, 0x00000000, 0xfffe0200,
dludwig@8563
   379
    0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001,
dludwig@8563
   380
    0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000,
dludwig@8563
   381
    0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000,
dludwig@8563
   382
    0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002,
dludwig@8563
   383
    0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000,
dludwig@8563
   384
    0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001,
dludwig@8563
   385
    0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004,
dludwig@8563
   386
    0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x03000005, 0x800f0001,
dludwig@8563
   387
    0x80550000, 0xa0e4000a, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40009,
dludwig@8563
   388
    0x80e40001, 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e4000b, 0x80e40001,
dludwig@8563
   389
    0x04000004, 0x800f0000, 0x80ff0000, 0xa0e4000c, 0x80e40001, 0x04000004,
dludwig@8563
   390
    0xc0030000, 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000,
dludwig@8563
   391
    0x80e40000, 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001,
dludwig@8563
   392
    0x90e40002, 0x0000ffff, 0x52444853, 0x00000258, 0x00010040, 0x00000096,
dludwig@8563
   393
    0x04000059, 0x00208e46, 0x00000000, 0x0000000c, 0x0300005f, 0x00101072,
dludwig@8563
   394
    0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2,
dludwig@8563
   395
    0x00000002, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065,
dludwig@8563
   396
    0x00102032, 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068,
dludwig@8563
   397
    0x00000002, 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000,
dludwig@8563
   398
    0x00208e46, 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000,
dludwig@8563
   399
    0x00101006, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46,
dludwig@8563
   400
    0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000,
dludwig@8563
   401
    0x00208e46, 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000,
dludwig@8563
   402
    0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000,
dludwig@8563
   403
    0x00000003, 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000,
dludwig@8563
   404
    0x00208e46, 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001,
dludwig@8563
   405
    0x00100006, 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46,
dludwig@8563
   406
    0x00000001, 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000,
dludwig@8563
   407
    0x00208e46, 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032,
dludwig@8563
   408
    0x001000f2, 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000,
dludwig@8563
   409
    0x00000007, 0x00100e46, 0x00000001, 0x08000038, 0x001000f2, 0x00000001,
dludwig@8563
   410
    0x00100556, 0x00000000, 0x00208e46, 0x00000000, 0x00000009, 0x0a000032,
dludwig@8563
   411
    0x001000f2, 0x00000001, 0x00100006, 0x00000000, 0x00208e46, 0x00000000,
dludwig@8563
   412
    0x00000008, 0x00100e46, 0x00000001, 0x0a000032, 0x001000f2, 0x00000001,
dludwig@8563
   413
    0x00100aa6, 0x00000000, 0x00208e46, 0x00000000, 0x0000000a, 0x00100e46,
dludwig@8563
   414
    0x00000001, 0x0a000032, 0x001020f2, 0x00000000, 0x00100ff6, 0x00000000,
dludwig@8563
   415
    0x00208e46, 0x00000000, 0x0000000b, 0x00100e46, 0x00000001, 0x05000036,
dludwig@8563
   416
    0x00102032, 0x00000001, 0x00101046, 0x00000001, 0x05000036, 0x001020f2,
dludwig@8563
   417
    0x00000002, 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074,
dludwig@8563
   418
    0x0000000f, 0x00000002, 0x00000000, 0x00000006, 0x00000004, 0x00000000,
dludwig@8563
   419
    0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   420
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   421
    0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   422
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452,
dludwig@8563
   423
    0x00000110, 0x00000001, 0x00000054, 0x00000001, 0x0000001c, 0xfffe0400,
dludwig@8563
   424
    0x00000100, 0x000000dc, 0x0000003c, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   425
    0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x74726556, 0x68537865,
dludwig@8563
   426
    0x72656461, 0x736e6f43, 0x746e6174, 0xabab0073, 0x0000003c, 0x00000003,
dludwig@8563
   427
    0x0000006c, 0x000000c0, 0x00000000, 0x00000000, 0x000000b4, 0x00000000,
dludwig@8563
   428
    0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x000000cc, 0x00000040,
dludwig@8563
   429
    0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x000000d1, 0x00000080,
dludwig@8563
   430
    0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x65646f6d, 0xabab006c,
dludwig@8563
   431
    0x00030002, 0x00040004, 0x00000000, 0x00000000, 0x77656976, 0x6f727000,
dludwig@8563
   432
    0x7463656a, 0x006e6f69, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029,
dludwig@8563
   433
    0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e,
dludwig@8563
   434
    0x30303239, 0x3336312e, 0xab003438, 0x4e475349, 0x00000068, 0x00000003,
dludwig@8563
   435
    0x00000008, 0x00000050, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
dludwig@8563
   436
    0x00000707, 0x00000059, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
dludwig@8563
   437
    0x00000303, 0x00000062, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
dludwig@8563
   438
    0x00000f0f, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044,
dludwig@8563
   439
    0x00524f4c, 0x4e47534f, 0x0000006c, 0x00000003, 0x00000008, 0x00000050,
dludwig@8563
   440
    0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c,
dludwig@8563
   441
    0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000c03, 0x00000065,
dludwig@8563
   442
    0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x505f5653,
dludwig@8563
   443
    0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f,
dludwig@8563
   444
};
dludwig@8563
   445
#elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
dludwig@8563
   446
static const DWORD D3D11_VertexShader[] = {
dludwig@8563
   447
    0x43425844, 0xacfd840a, 0x6a6ae1e1, 0xc3649c43, 0x8bfc0816, 0x00000001,
dludwig@8563
   448
    0x00000690, 0x00000006, 0x00000038, 0x000001b8, 0x00000418, 0x00000494,
dludwig@8563
   449
    0x000005ac, 0x0000061c, 0x396e6f41, 0x00000178, 0x00000178, 0xfffe0200,
dludwig@8563
   450
    0x00000144, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000,
dludwig@8563
   451
    0x00300001, 0x00000000, 0x0001000c, 0x00000000, 0x00000000, 0xfffe0201,
dludwig@8563
   452
    0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001,
dludwig@8563
   453
    0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000,
dludwig@8563
   454
    0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000,
dludwig@8563
   455
    0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002,
dludwig@8563
   456
    0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000,
dludwig@8563
   457
    0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001,
dludwig@8563
   458
    0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004,
dludwig@8563
   459
    0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x03000005, 0x800f0001,
dludwig@8563
   460
    0x80550000, 0xa0e4000a, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40009,
dludwig@8563
   461
    0x80e40001, 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e4000b, 0x80e40001,
dludwig@8563
   462
    0x04000004, 0x800f0000, 0x80ff0000, 0xa0e4000c, 0x80e40001, 0x04000004,
dludwig@8563
   463
    0xc0030000, 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000,
dludwig@8563
   464
    0x80e40000, 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001,
dludwig@8563
   465
    0x90e40002, 0x0000ffff, 0x52444853, 0x00000258, 0x00010040, 0x00000096,
dludwig@8563
   466
    0x04000059, 0x00208e46, 0x00000000, 0x0000000c, 0x0300005f, 0x00101072,
dludwig@8563
   467
    0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2,
dludwig@8563
   468
    0x00000002, 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065,
dludwig@8563
   469
    0x00102032, 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068,
dludwig@8563
   470
    0x00000002, 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000,
dludwig@8563
   471
    0x00208e46, 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000,
dludwig@8563
   472
    0x00101006, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46,
dludwig@8563
   473
    0x00000000, 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000,
dludwig@8563
   474
    0x00208e46, 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000,
dludwig@8563
   475
    0x001000f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000,
dludwig@8563
   476
    0x00000003, 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000,
dludwig@8563
   477
    0x00208e46, 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001,
dludwig@8563
   478
    0x00100006, 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46,
dludwig@8563
   479
    0x00000001, 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000,
dludwig@8563
   480
    0x00208e46, 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032,
dludwig@8563
   481
    0x001000f2, 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000,
dludwig@8563
   482
    0x00000007, 0x00100e46, 0x00000001, 0x08000038, 0x001000f2, 0x00000001,
dludwig@8563
   483
    0x00100556, 0x00000000, 0x00208e46, 0x00000000, 0x00000009, 0x0a000032,
dludwig@8563
   484
    0x001000f2, 0x00000001, 0x00100006, 0x00000000, 0x00208e46, 0x00000000,
dludwig@8563
   485
    0x00000008, 0x00100e46, 0x00000001, 0x0a000032, 0x001000f2, 0x00000001,
dludwig@8563
   486
    0x00100aa6, 0x00000000, 0x00208e46, 0x00000000, 0x0000000a, 0x00100e46,
dludwig@8563
   487
    0x00000001, 0x0a000032, 0x001020f2, 0x00000000, 0x00100ff6, 0x00000000,
dludwig@8563
   488
    0x00208e46, 0x00000000, 0x0000000b, 0x00100e46, 0x00000001, 0x05000036,
dludwig@8563
   489
    0x00102032, 0x00000001, 0x00101046, 0x00000001, 0x05000036, 0x001020f2,
dludwig@8563
   490
    0x00000002, 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074,
dludwig@8563
   491
    0x0000000f, 0x00000002, 0x00000000, 0x00000006, 0x00000004, 0x00000000,
dludwig@8563
   492
    0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   493
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   494
    0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   495
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452,
dludwig@8563
   496
    0x00000110, 0x00000001, 0x00000054, 0x00000001, 0x0000001c, 0xfffe0400,
dludwig@8563
   497
    0x00000100, 0x000000dc, 0x0000003c, 0x00000000, 0x00000000, 0x00000000,
dludwig@8563
   498
    0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x74726556, 0x68537865,
dludwig@8563
   499
    0x72656461, 0x736e6f43, 0x746e6174, 0xabab0073, 0x0000003c, 0x00000003,
dludwig@8563
   500
    0x0000006c, 0x000000c0, 0x00000000, 0x00000000, 0x000000b4, 0x00000000,
dludwig@8563
   501
    0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x000000cc, 0x00000040,
dludwig@8563
   502
    0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x000000d1, 0x00000080,
dludwig@8563
   503
    0x00000040, 0x00000002, 0x000000bc, 0x00000000, 0x65646f6d, 0xabab006c,
dludwig@8563
   504
    0x00030002, 0x00040004, 0x00000000, 0x00000000, 0x77656976, 0x6f727000,
dludwig@8563
   505
    0x7463656a, 0x006e6f69, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029,
dludwig@8563
   506
    0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e,
dludwig@8563
   507
    0x30303239, 0x3336312e, 0xab003438, 0x4e475349, 0x00000068, 0x00000003,
dludwig@8563
   508
    0x00000008, 0x00000050, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
dludwig@8563
   509
    0x00000707, 0x00000059, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
dludwig@8563
   510
    0x00000303, 0x00000062, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
dludwig@8563
   511
    0x00000f0f, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044,
dludwig@8563
   512
    0x00524f4c, 0x4e47534f, 0x0000006c, 0x00000003, 0x00000008, 0x00000050,
dludwig@8563
   513
    0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c,
dludwig@8563
   514
    0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000c03, 0x00000065,
dludwig@8563
   515
    0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x0000000f, 0x505f5653,
dludwig@8563
   516
    0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f
dludwig@8563
   517
};
dludwig@8563
   518
#else
dludwig@8563
   519
#error "An appropriate vertex shader is not defined."
dludwig@8563
   520
#endif
dludwig@8563
   521
dludwig@8410
   522
/* Direct3D 11.1 renderer implementation */
dludwig@8400
   523
static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags);
dludwig@8415
   524
static void D3D11_WindowEvent(SDL_Renderer * renderer,
dludwig@8415
   525
                            const SDL_WindowEvent *event);
dludwig@8416
   526
static int D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
dludwig@8416
   527
static int D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
dludwig@8459
   528
                             const SDL_Rect * rect, const void *srcPixels,
dludwig@8459
   529
                             int srcPitch);
dludwig@8451
   530
static int D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
dludwig@8451
   531
                             const SDL_Rect * rect, void **pixels, int *pitch);
dludwig@8451
   532
static void D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
dludwig@8459
   533
static int D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
dludwig@8400
   534
static int D3D11_UpdateViewport(SDL_Renderer * renderer);
dludwig@8482
   535
static int D3D11_UpdateClipRect(SDL_Renderer * renderer);
dludwig@8416
   536
static int D3D11_RenderClear(SDL_Renderer * renderer);
dludwig@8450
   537
static int D3D11_RenderDrawPoints(SDL_Renderer * renderer,
dludwig@8450
   538
                                  const SDL_FPoint * points, int count);
dludwig@8449
   539
static int D3D11_RenderDrawLines(SDL_Renderer * renderer,
dludwig@8449
   540
                                 const SDL_FPoint * points, int count);
dludwig@8429
   541
static int D3D11_RenderFillRects(SDL_Renderer * renderer,
dludwig@8429
   542
                                 const SDL_FRect * rects, int count);
dludwig@8416
   543
static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
dludwig@8416
   544
                            const SDL_Rect * srcrect, const SDL_FRect * dstrect);
dludwig@8455
   545
static int D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
dludwig@8455
   546
                              const SDL_Rect * srcrect, const SDL_FRect * dstrect,
dludwig@8455
   547
                              const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip);
dludwig@8454
   548
static int D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
dludwig@8454
   549
                                  Uint32 format, void * pixels, int pitch);
dludwig@8401
   550
static void D3D11_RenderPresent(SDL_Renderer * renderer);
dludwig@8416
   551
static void D3D11_DestroyTexture(SDL_Renderer * renderer,
dludwig@8416
   552
                                 SDL_Texture * texture);
dludwig@8413
   553
static void D3D11_DestroyRenderer(SDL_Renderer * renderer);
dludwig@8400
   554
dludwig@8410
   555
/* Direct3D 11.1 Internal Functions */
dludwig@8412
   556
HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer);
dludwig@8413
   557
HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer);
dludwig@8414
   558
HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer);
dludwig@8414
   559
HRESULT D3D11_HandleDeviceLost(SDL_Renderer * renderer);
dludwig@8400
   560
dludwig@8442
   561
extern "C" SDL_RenderDriver D3D11_RenderDriver = {
dludwig@8400
   562
    D3D11_CreateRenderer,
dludwig@8400
   563
    {
dludwig@8442
   564
        "direct3d 11.1",
dludwig@8459
   565
        (
dludwig@8459
   566
            SDL_RENDERER_ACCELERATED |
dludwig@8459
   567
            SDL_RENDERER_PRESENTVSYNC |
dludwig@8459
   568
            SDL_RENDERER_TARGETTEXTURE
dludwig@8459
   569
        ),                          // flags.  see SDL_RendererFlags
dludwig@8442
   570
        2,                          // num_texture_formats
dludwig@8442
   571
        {                           // texture_formats
dludwig@8442
   572
            SDL_PIXELFORMAT_RGB888,
dludwig@8442
   573
            SDL_PIXELFORMAT_ARGB8888
dludwig@8442
   574
        },
dludwig@8446
   575
        0,                          // max_texture_width: will be filled in later
dludwig@8446
   576
        0                           // max_texture_height: will be filled in later
dludwig@8442
   577
    }
dludwig@8442
   578
};
dludwig@8442
   579
dludwig@8400
   580
dludwig@8454
   581
static Uint32
dludwig@8454
   582
DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat) {
dludwig@8454
   583
    switch (dxgiFormat) {
dludwig@8454
   584
        case DXGI_FORMAT_B8G8R8A8_UNORM:
dludwig@8454
   585
            return SDL_PIXELFORMAT_ARGB8888;
dludwig@8454
   586
        case DXGI_FORMAT_B8G8R8X8_UNORM:
dludwig@8454
   587
            return SDL_PIXELFORMAT_RGB888;
dludwig@8454
   588
        default:
dludwig@8454
   589
            return SDL_PIXELFORMAT_UNKNOWN;
dludwig@8454
   590
    }
dludwig@8454
   591
}
dludwig@8454
   592
dludwig@8454
   593
static DXGI_FORMAT
dludwig@8454
   594
SDLPixelFormatToDXGIFormat(Uint32 sdlFormat)
dludwig@8454
   595
{
dludwig@8454
   596
    switch (sdlFormat) {
dludwig@8454
   597
        case SDL_PIXELFORMAT_ARGB8888:
dludwig@8454
   598
            return DXGI_FORMAT_B8G8R8A8_UNORM;
dludwig@8454
   599
        case SDL_PIXELFORMAT_RGB888:
dludwig@8454
   600
            return DXGI_FORMAT_B8G8R8X8_UNORM;
dludwig@8454
   601
        default:
dludwig@8454
   602
            return DXGI_FORMAT_UNKNOWN;
dludwig@8454
   603
    }
dludwig@8454
   604
}
dludwig@8454
   605
dludwig@8454
   606
dludwig@8400
   607
//typedef struct
dludwig@8400
   608
//{
dludwig@8400
   609
//    float x, y, z;
dludwig@8400
   610
//    DWORD color;
dludwig@8400
   611
//    float u, v;
dludwig@8400
   612
//} Vertex;
dludwig@8400
   613
dludwig@8400
   614
SDL_Renderer *
dludwig@8400
   615
D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
dludwig@8400
   616
{
dludwig@8400
   617
    SDL_Renderer *renderer;
dludwig@8400
   618
    D3D11_RenderData *data;
dludwig@8400
   619
dludwig@8400
   620
    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
dludwig@8400
   621
    if (!renderer) {
dludwig@8400
   622
        SDL_OutOfMemory();
dludwig@8400
   623
        return NULL;
dludwig@8400
   624
    }
dludwig@8400
   625
    SDL_zerop(renderer);
dludwig@8400
   626
dludwig@8400
   627
    data = new D3D11_RenderData;    // Use the C++ 'new' operator to make sure the struct's members initialize using C++ rules
dludwig@8400
   628
    if (!data) {
dludwig@8400
   629
        SDL_OutOfMemory();
dludwig@8400
   630
        return NULL;
dludwig@8400
   631
    }
dludwig@8410
   632
    data->featureLevel = (D3D_FEATURE_LEVEL) 0;
dludwig@8412
   633
    data->windowSizeInDIPs = XMFLOAT2(0, 0);
dludwig@8412
   634
    data->renderTargetSize = XMFLOAT2(0, 0);
dludwig@8400
   635
dludwig@8415
   636
    renderer->WindowEvent = D3D11_WindowEvent;
dludwig@8416
   637
    renderer->CreateTexture = D3D11_CreateTexture;
dludwig@8416
   638
    renderer->UpdateTexture = D3D11_UpdateTexture;
dludwig@8451
   639
    renderer->LockTexture = D3D11_LockTexture;
dludwig@8451
   640
    renderer->UnlockTexture = D3D11_UnlockTexture;
dludwig@8459
   641
    renderer->SetRenderTarget = D3D11_SetRenderTarget;
dludwig@8400
   642
    renderer->UpdateViewport = D3D11_UpdateViewport;
dludwig@8482
   643
    renderer->UpdateClipRect = D3D11_UpdateClipRect;
dludwig@8416
   644
    renderer->RenderClear = D3D11_RenderClear;
dludwig@8450
   645
    renderer->RenderDrawPoints = D3D11_RenderDrawPoints;
dludwig@8449
   646
    renderer->RenderDrawLines = D3D11_RenderDrawLines;
dludwig@8429
   647
    renderer->RenderFillRects = D3D11_RenderFillRects;
dludwig@8416
   648
    renderer->RenderCopy = D3D11_RenderCopy;
dludwig@8455
   649
    renderer->RenderCopyEx = D3D11_RenderCopyEx;
dludwig@8454
   650
    renderer->RenderReadPixels = D3D11_RenderReadPixels;
dludwig@8401
   651
    renderer->RenderPresent = D3D11_RenderPresent;
dludwig@8416
   652
    renderer->DestroyTexture = D3D11_DestroyTexture;
dludwig@8413
   653
    renderer->DestroyRenderer = D3D11_DestroyRenderer;
dludwig@8400
   654
    renderer->info = D3D11_RenderDriver.info;
dludwig@8400
   655
    renderer->driverdata = data;
dludwig@8400
   656
dludwig@8413
   657
    // HACK: make sure the SDL_Renderer references the SDL_Window data now, in
dludwig@8413
   658
    // order to give init functions access to the underlying window handle:
dludwig@8413
   659
    renderer->window = window;
dludwig@8400
   660
dludwig@8413
   661
    /* Initialize Direct3D resources */
dludwig@8413
   662
    if (FAILED(D3D11_CreateDeviceResources(renderer))) {
dludwig@8413
   663
        D3D11_DestroyRenderer(renderer);
dludwig@8413
   664
        return NULL;
dludwig@8413
   665
    }
dludwig@8413
   666
    if (FAILED(D3D11_CreateWindowSizeDependentResources(renderer))) {
dludwig@8413
   667
        D3D11_DestroyRenderer(renderer);
dludwig@8413
   668
        return NULL;
dludwig@8413
   669
    }
dludwig@8400
   670
dludwig@8416
   671
    // TODO, WinRT: fill in renderer->info.texture_formats where appropriate
dludwig@8416
   672
dludwig@8400
   673
    return renderer;
dludwig@8400
   674
}
dludwig@8400
   675
dludwig@8413
   676
static void
dludwig@8413
   677
D3D11_DestroyRenderer(SDL_Renderer * renderer)
dludwig@8413
   678
{
dludwig@8413
   679
    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8413
   680
    if (data) {
dludwig@8413
   681
        delete data;
dludwig@8413
   682
        data = NULL;
dludwig@8413
   683
    }
dludwig@8413
   684
}
dludwig@8413
   685
dludwig@8431
   686
static HRESULT
dludwig@8431
   687
D3D11_CreateBlendMode(SDL_Renderer * renderer,
dludwig@8431
   688
                      BOOL enableBlending,
dludwig@8431
   689
                      D3D11_BLEND srcBlend,
dludwig@8431
   690
                      D3D11_BLEND destBlend,
dludwig@8431
   691
                      ID3D11BlendState ** blendStateOutput)
dludwig@8431
   692
{
dludwig@8431
   693
    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8431
   694
    HRESULT result = S_OK;
dludwig@8431
   695
dludwig@8431
   696
    D3D11_BLEND_DESC blendDesc;
dludwig@8431
   697
    memset(&blendDesc, 0, sizeof(blendDesc));
dludwig@8431
   698
    blendDesc.AlphaToCoverageEnable = FALSE;
dludwig@8431
   699
    blendDesc.IndependentBlendEnable = FALSE;
dludwig@8431
   700
    blendDesc.RenderTarget[0].BlendEnable = enableBlending;
dludwig@8431
   701
    blendDesc.RenderTarget[0].SrcBlend = srcBlend;
dludwig@8431
   702
    blendDesc.RenderTarget[0].DestBlend = destBlend;
dludwig@8431
   703
    blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
dludwig@8431
   704
    blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
dludwig@8431
   705
    blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
dludwig@8431
   706
    blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
dludwig@8431
   707
    blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
dludwig@8431
   708
    result = data->d3dDevice->CreateBlendState(&blendDesc, blendStateOutput);
dludwig@8431
   709
    if (FAILED(result)) {
dludwig@8553
   710
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBlendState", result);
dludwig@8431
   711
        return result;
dludwig@8431
   712
    }
dludwig@8431
   713
dludwig@8431
   714
    return S_OK;
dludwig@8431
   715
}
dludwig@8431
   716
dludwig@8414
   717
// Create resources that depend on the device.
dludwig@8410
   718
HRESULT
dludwig@8412
   719
D3D11_CreateDeviceResources(SDL_Renderer * renderer)
dludwig@8410
   720
{
dludwig@8410
   721
    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8410
   722
dludwig@8410
   723
    // This flag adds support for surfaces with a different color channel ordering
dludwig@8410
   724
    // than the API default. It is required for compatibility with Direct2D.
dludwig@8410
   725
    UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
dludwig@8410
   726
dludwig@8533
   727
    // Make sure Direct3D's debugging feature gets used, if the app requests it.
dludwig@8563
   728
    //const char *hint = SDL_GetHint(SDL_HINT_RENDER_DIRECT3D11_DEBUG);
dludwig@8563
   729
    //if (hint) {
dludwig@8563
   730
    //    if (*hint == '1') {
dludwig@8533
   731
            creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
dludwig@8563
   732
    //    }
dludwig@8563
   733
    //}
dludwig@8410
   734
dludwig@8410
   735
    // This array defines the set of DirectX hardware feature levels this app will support.
dludwig@8410
   736
    // Note the ordering should be preserved.
dludwig@8410
   737
    // Don't forget to declare your application's minimum required feature level in its
dludwig@8410
   738
    // description.  All applications are assumed to support 9.1 unless otherwise stated.
dludwig@8410
   739
    D3D_FEATURE_LEVEL featureLevels[] = 
dludwig@8410
   740
    {
dludwig@8410
   741
        D3D_FEATURE_LEVEL_11_1,
dludwig@8410
   742
        D3D_FEATURE_LEVEL_11_0,
dludwig@8410
   743
        D3D_FEATURE_LEVEL_10_1,
dludwig@8410
   744
        D3D_FEATURE_LEVEL_10_0,
dludwig@8410
   745
        D3D_FEATURE_LEVEL_9_3,
dludwig@8410
   746
        D3D_FEATURE_LEVEL_9_2,
dludwig@8410
   747
        D3D_FEATURE_LEVEL_9_1
dludwig@8410
   748
    };
dludwig@8410
   749
dludwig@8410
   750
    // Create the Direct3D 11 API device object and a corresponding context.
dludwig@8410
   751
    ComPtr<ID3D11Device> device;
dludwig@8410
   752
    ComPtr<ID3D11DeviceContext> context;
dludwig@8410
   753
    HRESULT result = S_OK;
dludwig@8410
   754
    result = D3D11CreateDevice(
dludwig@8410
   755
        nullptr, // Specify nullptr to use the default adapter.
dludwig@8410
   756
        D3D_DRIVER_TYPE_HARDWARE,
dludwig@8410
   757
        nullptr,
dludwig@8410
   758
        creationFlags, // Set set debug and Direct2D compatibility flags.
dludwig@8410
   759
        featureLevels, // List of feature levels this app can support.
dludwig@8410
   760
        ARRAYSIZE(featureLevels),
dludwig@8410
   761
        D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
dludwig@8410
   762
        &device, // Returns the Direct3D device created.
dludwig@8410
   763
        &data->featureLevel, // Returns feature level of device created.
dludwig@8410
   764
        &context // Returns the device immediate context.
dludwig@8410
   765
        );
dludwig@8410
   766
    if (FAILED(result)) {
dludwig@8553
   767
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", D3D11CreateDevice", result);
dludwig@8410
   768
        return result;
dludwig@8410
   769
    }
dludwig@8410
   770
dludwig@8410
   771
    // Get the Direct3D 11.1 API device and context interfaces.
dludwig@8410
   772
    result = device.As(&(data->d3dDevice));
dludwig@8410
   773
    if (FAILED(result)) {
dludwig@8553
   774
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to ID3D11Device1", result);
dludwig@8410
   775
        return result;
dludwig@8410
   776
    }
dludwig@8410
   777
dludwig@8410
   778
    result = context.As(&data->d3dContext);
dludwig@8410
   779
    if (FAILED(result)) {
dludwig@8553
   780
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext to ID3D11DeviceContext1", result);
dludwig@8410
   781
        return result;
dludwig@8410
   782
    }
dludwig@8410
   783
dludwig@8410
   784
    //
dludwig@8446
   785
    // Make note of the maximum texture size
dludwig@8446
   786
    // Max texture sizes are documented on MSDN, at:
dludwig@8446
   787
    // http://msdn.microsoft.com/en-us/library/windows/apps/ff476876.aspx
dludwig@8446
   788
    //
dludwig@8446
   789
    switch (data->d3dDevice->GetFeatureLevel()) {
dludwig@8446
   790
        case D3D_FEATURE_LEVEL_11_1:
dludwig@8446
   791
        case D3D_FEATURE_LEVEL_11_0:
dludwig@8446
   792
            renderer->info.max_texture_width = renderer->info.max_texture_height = 16384;
dludwig@8446
   793
            break;
dludwig@8446
   794
dludwig@8446
   795
        case D3D_FEATURE_LEVEL_10_1:
dludwig@8446
   796
        case D3D_FEATURE_LEVEL_10_0:
dludwig@8446
   797
            renderer->info.max_texture_width = renderer->info.max_texture_height = 8192;
dludwig@8446
   798
            break;
dludwig@8446
   799
dludwig@8446
   800
        case D3D_FEATURE_LEVEL_9_3:
dludwig@8446
   801
            renderer->info.max_texture_width = renderer->info.max_texture_height = 4096;
dludwig@8446
   802
            break;
dludwig@8446
   803
dludwig@8446
   804
        case D3D_FEATURE_LEVEL_9_2:
dludwig@8446
   805
        case D3D_FEATURE_LEVEL_9_1:
dludwig@8446
   806
            renderer->info.max_texture_width = renderer->info.max_texture_height = 2048;
dludwig@8446
   807
            break;
dludwig@8446
   808
    }
dludwig@8446
   809
dludwig@8446
   810
    //
dludwig@8410
   811
    // Load in SDL's one and only vertex shader:
dludwig@8410
   812
    //
dludwig@8410
   813
    result = data->d3dDevice->CreateVertexShader(
dludwig@8563
   814
        D3D11_VertexShader,
dludwig@8563
   815
        sizeof(D3D11_VertexShader),
dludwig@8410
   816
        nullptr,
dludwig@8410
   817
        &data->vertexShader
dludwig@8410
   818
        );
dludwig@8410
   819
    if (FAILED(result)) {
dludwig@8553
   820
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateVertexShader", result);
dludwig@8410
   821
        return result;
dludwig@8410
   822
    }
dludwig@8410
   823
dludwig@8410
   824
    //
dludwig@8410
   825
    // Create an input layout for SDL's vertex shader:
dludwig@8410
   826
    //
dludwig@8410
   827
    const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = 
dludwig@8410
   828
    {
dludwig@8429
   829
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
dludwig@8410
   830
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
dludwig@8429
   831
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
dludwig@8410
   832
    };
dludwig@8410
   833
dludwig@8410
   834
    result = data->d3dDevice->CreateInputLayout(
dludwig@8410
   835
        vertexDesc,
dludwig@8410
   836
        ARRAYSIZE(vertexDesc),
dludwig@8563
   837
        D3D11_VertexShader,
dludwig@8563
   838
        sizeof(D3D11_VertexShader),
dludwig@8410
   839
        &data->inputLayout
dludwig@8410
   840
        );
dludwig@8410
   841
    if (FAILED(result)) {
dludwig@8553
   842
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateInputLayout", result);
dludwig@8410
   843
        return result;
dludwig@8410
   844
    }
dludwig@8410
   845
dludwig@8410
   846
    //
dludwig@8429
   847
    // Load in SDL's pixel shaders
dludwig@8410
   848
    //
dludwig@8563
   849
dludwig@8563
   850
    result = data->d3dDevice->CreatePixelShader(
dludwig@8563
   851
        D3D11_PixelShader_Textures,
dludwig@8563
   852
        sizeof(D3D11_PixelShader_Textures),
dludwig@8563
   853
        nullptr,
dludwig@8563
   854
        &data->texturePixelShader
dludwig@8563
   855
        );
dludwig@8429
   856
    if (FAILED(result)) {
dludwig@8563
   857
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['textures' shader]", result);
dludwig@8429
   858
        return result;
dludwig@8410
   859
    }
dludwig@8410
   860
dludwig@8563
   861
    result = data->d3dDevice->CreatePixelShader(
dludwig@8563
   862
        D3D11_PixelShader_Colors,
dludwig@8563
   863
        sizeof(D3D11_PixelShader_Colors),
dludwig@8563
   864
        nullptr,
dludwig@8563
   865
        &data->colorPixelShader
dludwig@8563
   866
        );
dludwig@8410
   867
    if (FAILED(result)) {
dludwig@8563
   868
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['color' shader]", result);
dludwig@8410
   869
        return result;
dludwig@8410
   870
    }
dludwig@8410
   871
dludwig@8410
   872
    //
dludwig@8418
   873
    // Setup space to hold vertex shader constants:
dludwig@8418
   874
    //
dludwig@8560
   875
    CD3D11_BUFFER_DESC constantBufferDesc(sizeof(VertexShaderConstants), D3D11_BIND_CONSTANT_BUFFER);
dludwig@8418
   876
    result = data->d3dDevice->CreateBuffer(
dludwig@8418
   877
		&constantBufferDesc,
dludwig@8418
   878
		nullptr,
dludwig@8418
   879
        &data->vertexShaderConstants
dludwig@8418
   880
		);
dludwig@8418
   881
    if (FAILED(result)) {
dludwig@8553
   882
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBuffer [vertex shader constants]", result);
dludwig@8418
   883
        return result;
dludwig@8418
   884
    }
dludwig@8418
   885
dludwig@8418
   886
    //
dludwig@8425
   887
    // Make sure that the vertex buffer, if already created, gets freed.
dludwig@8425
   888
    // It will be recreated later.
dludwig@8410
   889
    //
dludwig@8425
   890
    data->vertexBuffer = nullptr;
dludwig@8410
   891
dludwig@8410
   892
    //
dludwig@8540
   893
    // Create samplers to use when drawing textures:
dludwig@8410
   894
    //
dludwig@8410
   895
    D3D11_SAMPLER_DESC samplerDesc;
dludwig@8540
   896
    samplerDesc.Filter = SDL_D3D11_NEAREST_PIXEL_FILTER;
dludwig@8410
   897
    samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
dludwig@8410
   898
    samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
dludwig@8410
   899
    samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
dludwig@8410
   900
    samplerDesc.MipLODBias = 0.0f;
dludwig@8410
   901
    samplerDesc.MaxAnisotropy = 1;
dludwig@8410
   902
    samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
dludwig@8410
   903
    samplerDesc.BorderColor[0] = 0.0f;
dludwig@8410
   904
    samplerDesc.BorderColor[1] = 0.0f;
dludwig@8410
   905
    samplerDesc.BorderColor[2] = 0.0f;
dludwig@8410
   906
    samplerDesc.BorderColor[3] = 0.0f;
dludwig@8410
   907
    samplerDesc.MinLOD = 0.0f;
dludwig@8410
   908
    samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
dludwig@8410
   909
    result = data->d3dDevice->CreateSamplerState(
dludwig@8410
   910
        &samplerDesc,
dludwig@8540
   911
        &data->nearestPixelSampler
dludwig@8540
   912
        );
dludwig@8540
   913
    if (FAILED(result)) {
dludwig@8553
   914
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [nearest-pixel filter]", result);
dludwig@8540
   915
        return result;
dludwig@8540
   916
    }
dludwig@8540
   917
dludwig@8540
   918
    samplerDesc.Filter = SDL_D3D11_LINEAR_FILTER;
dludwig@8540
   919
    result = data->d3dDevice->CreateSamplerState(
dludwig@8540
   920
        &samplerDesc,
dludwig@8540
   921
        &data->linearSampler
dludwig@8410
   922
        );
dludwig@8410
   923
    if (FAILED(result)) {
dludwig@8553
   924
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [linear filter]", result);
dludwig@8410
   925
        return result;
dludwig@8410
   926
    }
dludwig@8410
   927
dludwig@8410
   928
    //
dludwig@8426
   929
    // Setup the Direct3D rasterizer
dludwig@8426
   930
    //
dludwig@8426
   931
    D3D11_RASTERIZER_DESC rasterDesc;
dludwig@8426
   932
    memset(&rasterDesc, 0, sizeof(rasterDesc));
dludwig@8426
   933
	rasterDesc.AntialiasedLineEnable = false;
dludwig@8426
   934
	rasterDesc.CullMode = D3D11_CULL_NONE;
dludwig@8426
   935
	rasterDesc.DepthBias = 0;
dludwig@8426
   936
	rasterDesc.DepthBiasClamp = 0.0f;
dludwig@8426
   937
	rasterDesc.DepthClipEnable = true;
dludwig@8426
   938
	rasterDesc.FillMode = D3D11_FILL_SOLID;
dludwig@8426
   939
	rasterDesc.FrontCounterClockwise = false;
dludwig@8426
   940
	rasterDesc.MultisampleEnable = false;
dludwig@8426
   941
	rasterDesc.ScissorEnable = false;
dludwig@8426
   942
	rasterDesc.SlopeScaledDepthBias = 0.0f;
dludwig@8426
   943
	result = data->d3dDevice->CreateRasterizerState(&rasterDesc, &data->mainRasterizer);
dludwig@8426
   944
	if (FAILED(result)) {
dludwig@8553
   945
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState", result);
dludwig@8426
   946
        return result;
dludwig@8426
   947
    }
dludwig@8426
   948
dludwig@8426
   949
    //
dludwig@8431
   950
    // Create blending states:
dludwig@8431
   951
    //
dludwig@8431
   952
    result = D3D11_CreateBlendMode(
dludwig@8431
   953
        renderer,
dludwig@8431
   954
        TRUE,
dludwig@8431
   955
        D3D11_BLEND_SRC_ALPHA,
dludwig@8431
   956
        D3D11_BLEND_INV_SRC_ALPHA,
dludwig@8431
   957
        &data->blendModeBlend);
dludwig@8431
   958
    if (FAILED(result)) {
dludwig@8431
   959
        // D3D11_CreateBlendMode will set the SDL error, if it fails
dludwig@8431
   960
        return result;
dludwig@8431
   961
    }
dludwig@8431
   962
dludwig@8431
   963
    result = D3D11_CreateBlendMode(
dludwig@8431
   964
        renderer,
dludwig@8431
   965
        TRUE,
dludwig@8431
   966
        D3D11_BLEND_SRC_ALPHA,
dludwig@8431
   967
        D3D11_BLEND_ONE,
dludwig@8431
   968
        &data->blendModeAdd);
dludwig@8431
   969
    if (FAILED(result)) {
dludwig@8431
   970
        // D3D11_CreateBlendMode will set the SDL error, if it fails
dludwig@8431
   971
        return result;
dludwig@8431
   972
    }
dludwig@8431
   973
dludwig@8431
   974
    result = D3D11_CreateBlendMode(
dludwig@8431
   975
        renderer,
dludwig@8431
   976
        TRUE,
dludwig@8431
   977
        D3D11_BLEND_ZERO,
dludwig@8431
   978
        D3D11_BLEND_SRC_COLOR,
dludwig@8431
   979
        &data->blendModeMod);
dludwig@8431
   980
    if (FAILED(result)) {
dludwig@8431
   981
        // D3D11_CreateBlendMode will set the SDL error, if it fails
dludwig@8431
   982
        return result;
dludwig@8431
   983
    }
dludwig@8431
   984
dludwig@8431
   985
    //
dludwig@8410
   986
    // All done!
dludwig@8410
   987
    //
dludwig@8410
   988
    return S_OK;
dludwig@8410
   989
}
dludwig@8410
   990
dludwig@8412
   991
#ifdef __WINRT__
dludwig@8412
   992
dludwig@8463
   993
static ABI::Windows::UI::Core::ICoreWindow *
dludwig@8412
   994
D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer)
dludwig@8412
   995
{
dludwig@8412
   996
    SDL_Window * sdlWindow = renderer->window;
dludwig@8412
   997
    if ( ! renderer->window ) {
dludwig@8412
   998
        return nullptr;
dludwig@8412
   999
    }
dludwig@8412
  1000
dludwig@8412
  1001
    SDL_SysWMinfo sdlWindowInfo;
dludwig@8412
  1002
    SDL_VERSION(&sdlWindowInfo.version);
dludwig@8412
  1003
    if ( ! SDL_GetWindowWMInfo(sdlWindow, &sdlWindowInfo) ) {
dludwig@8412
  1004
        return nullptr;
dludwig@8412
  1005
    }
dludwig@8412
  1006
dludwig@8496
  1007
    if (sdlWindowInfo.subsystem != SDL_SYSWM_WINRT) {
dludwig@8412
  1008
        return nullptr;
dludwig@8412
  1009
    }
dludwig@8412
  1010
dludwig@8463
  1011
    if ( ! sdlWindowInfo.info.winrt.window ) {
dludwig@8412
  1012
        return nullptr;
dludwig@8412
  1013
    }
dludwig@8412
  1014
dludwig@8463
  1015
    ABI::Windows::UI::Core::ICoreWindow * coreWindow = nullptr;
dludwig@8463
  1016
    if (FAILED(sdlWindowInfo.info.winrt.window->QueryInterface(&coreWindow))) {
dludwig@8463
  1017
        return nullptr;
dludwig@8463
  1018
    }
dludwig@8463
  1019
dludwig@8463
  1020
    return coreWindow;
dludwig@8412
  1021
}
dludwig@8412
  1022
dludwig@8414
  1023
// Method to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
dludwig@8412
  1024
static float
dludwig@8412
  1025
D3D11_ConvertDipsToPixels(float dips)
dludwig@8412
  1026
{
dludwig@8412
  1027
    static const float dipsPerInch = 96.0f;
dludwig@8412
  1028
    return floor(dips * DisplayProperties::LogicalDpi / dipsPerInch + 0.5f); // Round to nearest integer.
dludwig@8412
  1029
}
dludwig@8412
  1030
#endif
dludwig@8412
  1031
dludwig@8505
  1032
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
dludwig@8505
  1033
// TODO, WinRT, XAML: get the ISwapChainBackgroundPanelNative from something other than a global var
dludwig@8505
  1034
extern ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative;
dludwig@8505
  1035
#endif
dludwig@8505
  1036
dludwig@8548
  1037
static DXGI_MODE_ROTATION
dludwig@8548
  1038
D3D11_GetRotationForOrientation(Windows::Graphics::Display::DisplayOrientations orientation)
dludwig@8548
  1039
{
dludwig@8548
  1040
    switch (orientation)
dludwig@8548
  1041
    {
dludwig@8548
  1042
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
dludwig@8548
  1043
        //
dludwig@8548
  1044
        // Windows Phone rotations
dludwig@8548
  1045
        //
dludwig@8548
  1046
        case DisplayOrientations::Landscape:
dludwig@8548
  1047
            return DXGI_MODE_ROTATION_ROTATE90;
dludwig@8548
  1048
        case DisplayOrientations::Portrait:
dludwig@8548
  1049
            return DXGI_MODE_ROTATION_IDENTITY;
dludwig@8548
  1050
        case DisplayOrientations::LandscapeFlipped:
dludwig@8548
  1051
            return DXGI_MODE_ROTATION_ROTATE270;
dludwig@8548
  1052
        case DisplayOrientations::PortraitFlipped:
dludwig@8548
  1053
            return DXGI_MODE_ROTATION_ROTATE180;
dludwig@8548
  1054
#else
dludwig@8548
  1055
        //
dludwig@8548
  1056
        // Non-Windows-Phone rotations (ex: Windows 8, Windows RT)
dludwig@8548
  1057
        //
dludwig@8548
  1058
        case DisplayOrientations::Landscape:
dludwig@8548
  1059
            return DXGI_MODE_ROTATION_IDENTITY;
dludwig@8548
  1060
        case DisplayOrientations::Portrait:
dludwig@8548
  1061
            return DXGI_MODE_ROTATION_ROTATE270;
dludwig@8548
  1062
        case DisplayOrientations::LandscapeFlipped:
dludwig@8548
  1063
            return DXGI_MODE_ROTATION_ROTATE180;
dludwig@8548
  1064
        case DisplayOrientations::PortraitFlipped:
dludwig@8548
  1065
            return DXGI_MODE_ROTATION_ROTATE90;
dludwig@8548
  1066
#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
dludwig@8548
  1067
dludwig@8548
  1068
        default:
dludwig@8548
  1069
            return DXGI_MODE_ROTATION_UNSPECIFIED;
dludwig@8548
  1070
    }
dludwig@8548
  1071
}
dludwig@8505
  1072
dludwig@8414
  1073
// Initialize all resources that change when the window's size changes.
dludwig@8504
  1074
// TODO, WinRT: get D3D11_CreateWindowSizeDependentResources working on Win32
dludwig@8412
  1075
HRESULT
dludwig@8412
  1076
D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
dludwig@8412
  1077
{
dludwig@8412
  1078
    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8412
  1079
    HRESULT result = S_OK;
dludwig@8463
  1080
    ABI::Windows::UI::Core::ICoreWindow * coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer);
dludwig@8412
  1081
dludwig@8412
  1082
    // Store the window bounds so the next time we get a SizeChanged event we can
dludwig@8412
  1083
    // avoid rebuilding everything if the size is identical.
dludwig@8505
  1084
    ABI::Windows::Foundation::Rect nativeWindowBounds;
dludwig@8505
  1085
    if (coreWindow) {
dludwig@8505
  1086
        result = coreWindow->get_Bounds(&nativeWindowBounds);
dludwig@8505
  1087
        if (FAILED(result)) {
dludwig@8553
  1088
            WIN_SetErrorFromHRESULT(__FUNCTION__", ICoreWindow::get_Bounds [get native-window bounds]", result);
dludwig@8505
  1089
            return result;
dludwig@8505
  1090
        }
dludwig@8505
  1091
    } else {
dludwig@8505
  1092
        // TODO, WinRT, XAML: clean up window-bounds code in D3D11_CreateWindowSizeDependentResources
dludwig@8505
  1093
        SDL_DisplayMode displayMode;
dludwig@8505
  1094
        if (SDL_GetDesktopDisplayMode(0, &displayMode) < 0) {
dludwig@8505
  1095
            SDL_SetError(__FUNCTION__", Get Window Bounds (XAML): Unable to retrieve the native window's size");
dludwig@8505
  1096
            return E_FAIL;
dludwig@8505
  1097
        }
dludwig@8505
  1098
dludwig@8505
  1099
        nativeWindowBounds.Width = (FLOAT) displayMode.w;
dludwig@8505
  1100
        nativeWindowBounds.Height = (FLOAT) displayMode.h;
dludwig@8463
  1101
    }
dludwig@8463
  1102
dludwig@8505
  1103
    // TODO, WinRT, XAML: see if window/control sizes are in DIPs, or something else.  If something else, then adjust renderer size tracking accordingly.
dludwig@8505
  1104
    data->windowSizeInDIPs.x = nativeWindowBounds.Width;
dludwig@8505
  1105
    data->windowSizeInDIPs.y = nativeWindowBounds.Height;
dludwig@8412
  1106
dludwig@8412
  1107
    // Calculate the necessary swap chain and render target size in pixels.
dludwig@8412
  1108
    float windowWidth = D3D11_ConvertDipsToPixels(data->windowSizeInDIPs.x);
dludwig@8412
  1109
    float windowHeight = D3D11_ConvertDipsToPixels(data->windowSizeInDIPs.y);
dludwig@8412
  1110
dludwig@8412
  1111
    // The width and height of the swap chain must be based on the window's
dludwig@8412
  1112
    // landscape-oriented width and height. If the window is in a portrait
dludwig@8412
  1113
    // orientation, the dimensions must be reversed.
dludwig@8412
  1114
    data->orientation = DisplayProperties::CurrentOrientation;
dludwig@8508
  1115
dludwig@8508
  1116
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
dludwig@8508
  1117
    const bool swapDimensions = false;
dludwig@8508
  1118
#else
dludwig@8433
  1119
    const bool swapDimensions =
dludwig@8412
  1120
        data->orientation == DisplayOrientations::Portrait ||
dludwig@8412
  1121
        data->orientation == DisplayOrientations::PortraitFlipped;
dludwig@8508
  1122
#endif
dludwig@8412
  1123
    data->renderTargetSize.x = swapDimensions ? windowHeight : windowWidth;
dludwig@8412
  1124
    data->renderTargetSize.y = swapDimensions ? windowWidth : windowHeight;
dludwig@8412
  1125
dludwig@8412
  1126
    if(data->swapChain != nullptr)
dludwig@8412
  1127
    {
dludwig@8412
  1128
        // If the swap chain already exists, resize it.
dludwig@8412
  1129
        result = data->swapChain->ResizeBuffers(
dludwig@8412
  1130
            2, // Double-buffered swap chain.
dludwig@8412
  1131
            static_cast<UINT>(data->renderTargetSize.x),
dludwig@8412
  1132
            static_cast<UINT>(data->renderTargetSize.y),
dludwig@8412
  1133
            DXGI_FORMAT_B8G8R8A8_UNORM,
dludwig@8412
  1134
            0
dludwig@8412
  1135
            );
dludwig@8412
  1136
        if (FAILED(result)) {
dludwig@8553
  1137
            WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::ResizeBuffers", result);
dludwig@8412
  1138
            return result;
dludwig@8412
  1139
        }
dludwig@8412
  1140
    }
dludwig@8412
  1141
    else
dludwig@8412
  1142
    {
dludwig@8505
  1143
        const bool usingXAML = (coreWindow == nullptr);
dludwig@8505
  1144
dludwig@8412
  1145
        // Otherwise, create a new one using the same adapter as the existing Direct3D device.
dludwig@8412
  1146
        DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
dludwig@8412
  1147
        swapChainDesc.Width = static_cast<UINT>(data->renderTargetSize.x); // Match the size of the window.
dludwig@8412
  1148
        swapChainDesc.Height = static_cast<UINT>(data->renderTargetSize.y);
dludwig@8412
  1149
        swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
dludwig@8412
  1150
        swapChainDesc.Stereo = false;
dludwig@8412
  1151
        swapChainDesc.SampleDesc.Count = 1; // Don't use multi-sampling.
dludwig@8412
  1152
        swapChainDesc.SampleDesc.Quality = 0;
dludwig@8412
  1153
        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
dludwig@8412
  1154
        swapChainDesc.BufferCount = 2; // Use double-buffering to minimize latency.
dludwig@8412
  1155
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
dludwig@8412
  1156
        swapChainDesc.Scaling = DXGI_SCALING_STRETCH; // On phone, only stretch and aspect-ratio stretch scaling are allowed.
dludwig@8412
  1157
        swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // On phone, no swap effects are supported.
dludwig@8412
  1158
#else
dludwig@8505
  1159
        if (usingXAML) {
dludwig@8505
  1160
            swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
dludwig@8505
  1161
        } else {
dludwig@8505
  1162
            swapChainDesc.Scaling = DXGI_SCALING_NONE;
dludwig@8505
  1163
        }
dludwig@8412
  1164
        swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect.
dludwig@8412
  1165
#endif
dludwig@8412
  1166
        swapChainDesc.Flags = 0;
dludwig@8412
  1167
dludwig@8555
  1168
        ComPtr<IDXGIDevice1> dxgiDevice;
dludwig@8412
  1169
        result = data->d3dDevice.As(&dxgiDevice);
dludwig@8412
  1170
        if (FAILED(result)) {
dludwig@8553
  1171
            WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1 to IDXGIDevice1", result);
dludwig@8412
  1172
            return result;
dludwig@8412
  1173
        }
dludwig@8412
  1174
dludwig@8412
  1175
        ComPtr<IDXGIAdapter> dxgiAdapter;
dludwig@8412
  1176
        result = dxgiDevice->GetAdapter(&dxgiAdapter);
dludwig@8412
  1177
        if (FAILED(result)) {
dludwig@8553
  1178
            WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIDevice1::GetAdapter", result);
dludwig@8412
  1179
            return result;
dludwig@8412
  1180
        }
dludwig@8412
  1181
dludwig@8412
  1182
        ComPtr<IDXGIFactory2> dxgiFactory;
dludwig@8412
  1183
        result = dxgiAdapter->GetParent(
dludwig@8412
  1184
            __uuidof(IDXGIFactory2), 
dludwig@8412
  1185
            &dxgiFactory
dludwig@8412
  1186
            );
dludwig@8412
  1187
        if (FAILED(result)) {
dludwig@8553
  1188
            WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIAdapter::GetParent", result);
dludwig@8412
  1189
            return result;
dludwig@8412
  1190
        }
dludwig@8412
  1191
dludwig@8505
  1192
        if (usingXAML) {
dludwig@8505
  1193
            result = dxgiFactory->CreateSwapChainForComposition(
dludwig@8505
  1194
                data->d3dDevice.Get(),
dludwig@8505
  1195
                &swapChainDesc,
dludwig@8505
  1196
                nullptr,
dludwig@8505
  1197
                &data->swapChain);
dludwig@8505
  1198
            if (FAILED(result)) {
dludwig@8553
  1199
                WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForComposition", result);
dludwig@8505
  1200
                return result;
dludwig@8505
  1201
            }
dludwig@8505
  1202
dludwig@8505
  1203
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
dludwig@8505
  1204
            result = WINRT_GlobalSwapChainBackgroundPanelNative->SetSwapChain(data->swapChain.Get());
dludwig@8505
  1205
            if (FAILED(result)) {
dludwig@8505
  1206
                WIN_SetErrorFromHRESULT(__FUNCTION__ ", ISwapChainBackgroundPanelNative::SetSwapChain", result);
dludwig@8505
  1207
                return result;
dludwig@8505
  1208
            }
dludwig@8505
  1209
#else
dludwig@8505
  1210
            SDL_SetError(__FUNCTION__ ", XAML support is not yet available for Windows Phone");
dludwig@8505
  1211
            return E_FAIL;
dludwig@8505
  1212
#endif
dludwig@8505
  1213
        } else {
dludwig@8505
  1214
            IUnknown * coreWindowAsIUnknown = nullptr;
dludwig@8505
  1215
            result = coreWindow->QueryInterface(&coreWindowAsIUnknown);
dludwig@8505
  1216
            if (FAILED(result)) {
dludwig@8553
  1217
                WIN_SetErrorFromHRESULT(__FUNCTION__ ", ICoreWindow to IUnknown", result);
dludwig@8505
  1218
                return result;
dludwig@8505
  1219
            }
dludwig@8505
  1220
dludwig@8505
  1221
            result = dxgiFactory->CreateSwapChainForCoreWindow(
dludwig@8505
  1222
                data->d3dDevice.Get(),
dludwig@8505
  1223
                coreWindowAsIUnknown,
dludwig@8505
  1224
                &swapChainDesc,
dludwig@8505
  1225
                nullptr, // Allow on all displays.
dludwig@8505
  1226
                &data->swapChain
dludwig@8505
  1227
                );
dludwig@8505
  1228
            if (FAILED(result)) {
dludwig@8553
  1229
                WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForCoreWindow", result);
dludwig@8505
  1230
                return result;
dludwig@8505
  1231
            }
dludwig@8463
  1232
        }
dludwig@8505
  1233
        
dludwig@8412
  1234
        // Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
dludwig@8412
  1235
        // ensures that the application will only render after each VSync, minimizing power consumption.
dludwig@8412
  1236
        result = dxgiDevice->SetMaximumFrameLatency(1);
dludwig@8412
  1237
        if (FAILED(result)) {
dludwig@8553
  1238
            WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIDevice1::SetMaximumFrameLatency", result);
dludwig@8412
  1239
            return result;
dludwig@8412
  1240
        }
dludwig@8412
  1241
    }
dludwig@8412
  1242
    
dludwig@8508
  1243
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
dludwig@8412
  1244
    // Set the proper orientation for the swap chain, and generate the
dludwig@8412
  1245
    // 3D matrix transformation for rendering to the rotated swap chain.
dludwig@8509
  1246
    //
dludwig@8548
  1247
    // To note, the call for this, IDXGISwapChain1::SetRotation, is not necessary
dludwig@8548
  1248
    // on Windows Phone, nor is it supported there.  It's only needed in Windows 8/RT.
dludwig@8548
  1249
    DXGI_MODE_ROTATION rotation = D3D11_GetRotationForOrientation(data->orientation);
dludwig@8412
  1250
    result = data->swapChain->SetRotation(rotation);
dludwig@8412
  1251
    if (FAILED(result)) {
dludwig@8553
  1252
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::SetRotation" , result);
dludwig@8412
  1253
        return result;
dludwig@8412
  1254
    }
dludwig@8412
  1255
#endif
dludwig@8412
  1256
dludwig@8412
  1257
    // Create a render target view of the swap chain back buffer.
dludwig@8412
  1258
    ComPtr<ID3D11Texture2D> backBuffer;
dludwig@8412
  1259
    result = data->swapChain->GetBuffer(
dludwig@8412
  1260
        0,
dludwig@8412
  1261
        __uuidof(ID3D11Texture2D),
dludwig@8412
  1262
        &backBuffer
dludwig@8412
  1263
        );
dludwig@8412
  1264
    if (FAILED(result)) {
dludwig@8553
  1265
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::GetBuffer [back-buffer]", result);
dludwig@8412
  1266
        return result;
dludwig@8412
  1267
    }
dludwig@8412
  1268
dludwig@8412
  1269
    result = data->d3dDevice->CreateRenderTargetView(
dludwig@8412
  1270
        backBuffer.Get(),
dludwig@8412
  1271
        nullptr,
dludwig@8459
  1272
        &data->mainRenderTargetView
dludwig@8412
  1273
        );
dludwig@8412
  1274
    if (FAILED(result)) {
dludwig@8553
  1275
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRenderTargetView", result);
dludwig@8412
  1276
        return result;
dludwig@8412
  1277
    }
dludwig@8412
  1278
dludwig@8432
  1279
    if (D3D11_UpdateViewport(renderer) != 0) {
dludwig@8432
  1280
        // D3D11_UpdateViewport will set the SDL error if it fails.
dludwig@8432
  1281
        return E_FAIL;
dludwig@8432
  1282
    }
dludwig@8412
  1283
dludwig@8412
  1284
    return S_OK;
dludwig@8412
  1285
}
dludwig@8412
  1286
dludwig@8415
  1287
// This method is called when the window's size changes.
dludwig@8414
  1288
HRESULT
dludwig@8414
  1289
D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer)
dludwig@8414
  1290
{
dludwig@8414
  1291
    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8414
  1292
    HRESULT result = S_OK;
dludwig@8463
  1293
    ABI::Windows::UI::Core::ICoreWindow * coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer);
dludwig@8463
  1294
    ABI::Windows::Foundation::Rect coreWindowBounds;
dludwig@8414
  1295
dludwig@8463
  1296
    result = coreWindow->get_Bounds(&coreWindowBounds);
dludwig@8463
  1297
    if (FAILED(result)) {
dludwig@8553
  1298
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ICoreWindow::get_Bounds [get window bounds]", result);
dludwig@8463
  1299
        return result;
dludwig@8463
  1300
    }
dludwig@8463
  1301
dludwig@8463
  1302
    if (coreWindowBounds.Width  != data->windowSizeInDIPs.x ||
dludwig@8463
  1303
        coreWindowBounds.Height != data->windowSizeInDIPs.y ||
dludwig@8414
  1304
        data->orientation != DisplayProperties::CurrentOrientation)
dludwig@8414
  1305
    {
dludwig@8414
  1306
        ID3D11RenderTargetView* nullViews[] = {nullptr};
dludwig@8414
  1307
        data->d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
dludwig@8459
  1308
        data->mainRenderTargetView = nullptr;
dludwig@8414
  1309
        data->d3dContext->Flush();
dludwig@8414
  1310
        result = D3D11_CreateWindowSizeDependentResources(renderer);
dludwig@8414
  1311
        if (FAILED(result)) {
dludwig@8554
  1312
            /* D3D11_CreateWindowSizeDependentResources will set the SDL error */
dludwig@8414
  1313
            return result;
dludwig@8414
  1314
        }
dludwig@8414
  1315
    }
dludwig@8414
  1316
dludwig@8414
  1317
    return S_OK;
dludwig@8414
  1318
}
dludwig@8414
  1319
dludwig@8414
  1320
HRESULT
dludwig@8414
  1321
D3D11_HandleDeviceLost(SDL_Renderer * renderer)
dludwig@8414
  1322
{
dludwig@8414
  1323
    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8414
  1324
    HRESULT result = S_OK;
dludwig@8414
  1325
dludwig@8415
  1326
    // Reset these member variables to ensure that D3D11_UpdateForWindowSizeChange recreates all resources.
dludwig@8414
  1327
    data->windowSizeInDIPs.x = 0;
dludwig@8414
  1328
    data->windowSizeInDIPs.y = 0;
dludwig@8414
  1329
    data->swapChain = nullptr;
dludwig@8414
  1330
dludwig@8414
  1331
    result = D3D11_CreateDeviceResources(renderer);
dludwig@8414
  1332
    if (FAILED(result)) {
dludwig@8554
  1333
        /* D3D11_CreateDeviceResources will set the SDL error */
dludwig@8414
  1334
        return result;
dludwig@8414
  1335
    }
dludwig@8414
  1336
dludwig@8414
  1337
    result = D3D11_UpdateForWindowSizeChange(renderer);
dludwig@8414
  1338
    if (FAILED(result)) {
dludwig@8554
  1339
        /* D3D11_UpdateForWindowSizeChange will set the SDL error */
dludwig@8414
  1340
        return result;
dludwig@8414
  1341
    }
dludwig@8414
  1342
dludwig@8414
  1343
    return S_OK;
dludwig@8414
  1344
}
dludwig@8414
  1345
dludwig@8415
  1346
static void
dludwig@8415
  1347
D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
dludwig@8415
  1348
{
dludwig@8415
  1349
    //D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8415
  1350
dludwig@8510
  1351
    if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
dludwig@8415
  1352
        D3D11_UpdateForWindowSizeChange(renderer);
dludwig@8415
  1353
    }
dludwig@8415
  1354
}
dludwig@8415
  1355
dludwig@8540
  1356
static D3D11_FILTER
dludwig@8540
  1357
GetScaleQuality(void)
dludwig@8540
  1358
{
dludwig@8540
  1359
    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
dludwig@8540
  1360
    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
dludwig@8540
  1361
        return SDL_D3D11_NEAREST_PIXEL_FILTER;
dludwig@8540
  1362
    } else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ {
dludwig@8540
  1363
        return SDL_D3D11_LINEAR_FILTER;
dludwig@8540
  1364
    }
dludwig@8540
  1365
}
dludwig@8540
  1366
dludwig@8416
  1367
static int
dludwig@8416
  1368
D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
dludwig@8416
  1369
{
dludwig@8416
  1370
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8416
  1371
    D3D11_TextureData *textureData;
dludwig@8416
  1372
    HRESULT result;
dludwig@8454
  1373
    DXGI_FORMAT textureFormat = SDLPixelFormatToDXGIFormat(texture->format);
dludwig@8454
  1374
    if (textureFormat == SDL_PIXELFORMAT_UNKNOWN) {
dludwig@8556
  1375
        return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified",
dludwig@8454
  1376
            __FUNCTION__, texture->format);
dludwig@8442
  1377
    }
dludwig@8416
  1378
dludwig@8416
  1379
    textureData = new D3D11_TextureData;
dludwig@8416
  1380
    if (!textureData) {
dludwig@8416
  1381
        SDL_OutOfMemory();
dludwig@8416
  1382
        return -1;
dludwig@8416
  1383
    }
dludwig@8416
  1384
    textureData->pixelFormat = SDL_AllocFormat(texture->format);
dludwig@8451
  1385
    textureData->lockedTexturePosition = XMINT2(0, 0);
dludwig@8540
  1386
    textureData->scaleMode = GetScaleQuality();
dludwig@8416
  1387
dludwig@8416
  1388
    texture->driverdata = textureData;
dludwig@8416
  1389
dludwig@8416
  1390
    D3D11_TEXTURE2D_DESC textureDesc = {0};
dludwig@8416
  1391
    textureDesc.Width = texture->w;
dludwig@8416
  1392
    textureDesc.Height = texture->h;
dludwig@8416
  1393
    textureDesc.MipLevels = 1;
dludwig@8416
  1394
    textureDesc.ArraySize = 1;
dludwig@8442
  1395
    textureDesc.Format = textureFormat;
dludwig@8416
  1396
    textureDesc.SampleDesc.Count = 1;
dludwig@8416
  1397
    textureDesc.SampleDesc.Quality = 0;
dludwig@8416
  1398
    textureDesc.MiscFlags = 0;
dludwig@8416
  1399
dludwig@8459
  1400
    if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
dludwig@8459
  1401
        textureDesc.Usage = D3D11_USAGE_DYNAMIC;
dludwig@8459
  1402
        textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
dludwig@8459
  1403
    } else {
dludwig@8459
  1404
        textureDesc.Usage = D3D11_USAGE_DEFAULT;
dludwig@8459
  1405
        textureDesc.CPUAccessFlags = 0;
dludwig@8459
  1406
    }
dludwig@8459
  1407
dludwig@8459
  1408
    if (texture->access == SDL_TEXTUREACCESS_TARGET) {
dludwig@8459
  1409
        textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
dludwig@8459
  1410
    } else {
dludwig@8459
  1411
        textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
dludwig@8459
  1412
    }
dludwig@8459
  1413
dludwig@8452
  1414
#if 0
dludwig@8452
  1415
    // Fill the texture with a non-black color, for debugging purposes:
dludwig@8416
  1416
    const int numPixels = textureDesc.Width * textureDesc.Height;
dludwig@8452
  1417
    const int pixelSizeInBytes = textureData->pixelFormat->BytesPerPixel;
dludwig@8416
  1418
    std::vector<uint8> initialTexturePixels(numPixels * pixelSizeInBytes, 0x00);
dludwig@8452
  1419
    for (int i = 0; i < (numPixels * pixelSizeInBytes); i += pixelSizeInBytes) {
dludwig@8452
  1420
        initialTexturePixels[i+0] = 0xff;
dludwig@8452
  1421
        initialTexturePixels[i+1] = 0xff;
dludwig@8452
  1422
        initialTexturePixels[i+2] = 0x00;
dludwig@8452
  1423
        initialTexturePixels[i+3] = 0xff;
dludwig@8452
  1424
    }
dludwig@8416
  1425
    D3D11_SUBRESOURCE_DATA initialTextureData = {0};
dludwig@8416
  1426
    initialTextureData.pSysMem = (void *)&(initialTexturePixels[0]);
dludwig@8416
  1427
    initialTextureData.SysMemPitch = textureDesc.Width * pixelSizeInBytes;
dludwig@8416
  1428
    initialTextureData.SysMemSlicePitch = numPixels * pixelSizeInBytes;
dludwig@8452
  1429
#endif
dludwig@8452
  1430
dludwig@8416
  1431
    result = rendererData->d3dDevice->CreateTexture2D(
dludwig@8416
  1432
        &textureDesc,
dludwig@8452
  1433
        NULL,   // &initialTextureData,
dludwig@8416
  1434
        &textureData->mainTexture
dludwig@8416
  1435
        );
dludwig@8416
  1436
    if (FAILED(result)) {
dludwig@8416
  1437
        D3D11_DestroyTexture(renderer, texture);
dludwig@8553
  1438
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D", result);
dludwig@8416
  1439
        return -1;
dludwig@8416
  1440
    }
dludwig@8416
  1441
dludwig@8459
  1442
    if (texture->access & SDL_TEXTUREACCESS_TARGET) {
dludwig@8459
  1443
        D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
dludwig@8459
  1444
        renderTargetViewDesc.Format = textureDesc.Format;
dludwig@8459
  1445
        renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
dludwig@8459
  1446
        renderTargetViewDesc.Texture2D.MipSlice = 0;
dludwig@8459
  1447
dludwig@8459
  1448
        result = rendererData->d3dDevice->CreateRenderTargetView(
dludwig@8459
  1449
            textureData->mainTexture.Get(),
dludwig@8459
  1450
            &renderTargetViewDesc,
dludwig@8459
  1451
            &textureData->mainTextureRenderTargetView);
dludwig@8459
  1452
        if (FAILED(result)) {
dludwig@8459
  1453
            D3D11_DestroyTexture(renderer, texture);
dludwig@8553
  1454
            WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRenderTargetView", result);
dludwig@8459
  1455
            return -1;
dludwig@8459
  1456
        }
dludwig@8459
  1457
    }
dludwig@8459
  1458
dludwig@8416
  1459
    D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
dludwig@8416
  1460
    resourceViewDesc.Format = textureDesc.Format;
dludwig@8416
  1461
    resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
dludwig@8416
  1462
    resourceViewDesc.Texture2D.MostDetailedMip = 0;
dludwig@8416
  1463
    resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
dludwig@8416
  1464
    result = rendererData->d3dDevice->CreateShaderResourceView(
dludwig@8416
  1465
        textureData->mainTexture.Get(),
dludwig@8416
  1466
        &resourceViewDesc,
dludwig@8416
  1467
        &textureData->mainTextureResourceView
dludwig@8416
  1468
        );
dludwig@8416
  1469
    if (FAILED(result)) {
dludwig@8416
  1470
        D3D11_DestroyTexture(renderer, texture);
dludwig@8553
  1471
        WIN_SetErrorFromHRESULT(__FUNCTION__ "ID3D11Device1::CreateShaderResourceView", result);
dludwig@8416
  1472
        return -1;
dludwig@8416
  1473
    }
dludwig@8416
  1474
dludwig@8416
  1475
    return 0;
dludwig@8416
  1476
}
dludwig@8416
  1477
dludwig@8416
  1478
static void
dludwig@8416
  1479
D3D11_DestroyTexture(SDL_Renderer * renderer,
dludwig@8416
  1480
                     SDL_Texture * texture)
dludwig@8416
  1481
{
dludwig@8416
  1482
    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
dludwig@8416
  1483
dludwig@8416
  1484
    if (textureData) {
dludwig@8416
  1485
        if (textureData->pixelFormat) {
dludwig@8416
  1486
            SDL_FreeFormat(textureData->pixelFormat);
dludwig@8416
  1487
            textureData->pixelFormat = NULL;
dludwig@8416
  1488
        }
dludwig@8416
  1489
dludwig@8416
  1490
        delete textureData;
dludwig@8416
  1491
        texture->driverdata = NULL;
dludwig@8416
  1492
    }
dludwig@8416
  1493
}
dludwig@8416
  1494
dludwig@8416
  1495
static int
dludwig@8416
  1496
D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
dludwig@8459
  1497
                    const SDL_Rect * rect, const void * srcPixels,
dludwig@8459
  1498
                    int srcPitch)
dludwig@8416
  1499
{
dludwig@8459
  1500
    // Lock the texture, retrieving a buffer to write pixel data to:
dludwig@8459
  1501
    void * destPixels = NULL;
dludwig@8459
  1502
    int destPitch = 0;
dludwig@8459
  1503
    if (D3D11_LockTexture(renderer, texture, rect, &destPixels, &destPitch) != 0) {
dludwig@8459
  1504
        // An error is already set.  Attach some info to it, then return to
dludwig@8459
  1505
        // the caller.
dludwig@8459
  1506
        std::string errorMessage = string(__FUNCTION__ ", Lock Texture Failed: ") + SDL_GetError();
dludwig@8556
  1507
        return SDL_SetError(errorMessage.c_str());
dludwig@8416
  1508
    }
dludwig@8416
  1509
dludwig@8416
  1510
    // Copy pixel data to the locked texture's memory:
dludwig@8416
  1511
    for (int y = 0; y < rect->h; ++y) {
dludwig@8416
  1512
        memcpy(
dludwig@8459
  1513
            ((Uint8 *)destPixels) + (destPitch * y),
dludwig@8459
  1514
            ((Uint8 *)srcPixels) + (srcPitch * y),
dludwig@8459
  1515
            srcPitch
dludwig@8416
  1516
            );
dludwig@8416
  1517
    }
dludwig@8416
  1518
dludwig@8459
  1519
    // Commit the texture's memory back to Direct3D:
dludwig@8459
  1520
    D3D11_UnlockTexture(renderer, texture);
dludwig@8416
  1521
dludwig@8459
  1522
    // Return to the caller:
dludwig@8416
  1523
    return 0;
dludwig@8416
  1524
}
dludwig@8416
  1525
dludwig@8400
  1526
static int
dludwig@8451
  1527
D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
dludwig@8451
  1528
                  const SDL_Rect * rect, void **pixels, int *pitch)
dludwig@8451
  1529
{
dludwig@8451
  1530
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8451
  1531
    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
dludwig@8451
  1532
    HRESULT result = S_OK;
dludwig@8451
  1533
dludwig@8451
  1534
    if (textureData->stagingTexture) {
dludwig@8556
  1535
        return SDL_SetError("texture is already locked");
dludwig@8451
  1536
    }
dludwig@8451
  1537
    
dludwig@8451
  1538
    // Create a 'staging' texture, which will be used to write to a portion
dludwig@8451
  1539
    // of the main texture.  This is necessary, as Direct3D 11.1 does not
dludwig@8451
  1540
    // have the ability to write a CPU-bound pixel buffer to a rectangular
dludwig@8451
  1541
    // subrect of a texture.  Direct3D 11.1 can, however, write a pixel
dludwig@8451
  1542
    // buffer to an entire texture, hence the use of a staging texture.
dludwig@8561
  1543
    //
dludwig@8561
  1544
    // TODO, WinRT: consider avoiding the use of a staging texture in D3D11_LockTexture if/when the entire texture is being updated
dludwig@8451
  1545
    D3D11_TEXTURE2D_DESC stagingTextureDesc;
dludwig@8451
  1546
    textureData->mainTexture->GetDesc(&stagingTextureDesc);
dludwig@8451
  1547
    stagingTextureDesc.Width = rect->w;
dludwig@8451
  1548
    stagingTextureDesc.Height = rect->h;
dludwig@8451
  1549
    stagingTextureDesc.BindFlags = 0;
dludwig@8451
  1550
    stagingTextureDesc.MiscFlags = 0;
dludwig@8451
  1551
    stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
dludwig@8451
  1552
    stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
dludwig@8451
  1553
    result = rendererData->d3dDevice->CreateTexture2D(
dludwig@8451
  1554
        &stagingTextureDesc,
dludwig@8451
  1555
        NULL,
dludwig@8451
  1556
        &textureData->stagingTexture);
dludwig@8451
  1557
    if (FAILED(result)) {
dludwig@8553
  1558
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result);
dludwig@8451
  1559
        return -1;
dludwig@8451
  1560
    }
dludwig@8451
  1561
dludwig@8451
  1562
    // Get a write-only pointer to data in the staging texture:
dludwig@8451
  1563
    D3D11_MAPPED_SUBRESOURCE textureMemory = {0};
dludwig@8451
  1564
    result = rendererData->d3dContext->Map(
dludwig@8451
  1565
        textureData->stagingTexture.Get(),
dludwig@8451
  1566
        D3D11CalcSubresource(0, 0, 0),
dludwig@8451
  1567
        D3D11_MAP_WRITE,
dludwig@8451
  1568
        0,
dludwig@8451
  1569
        &textureMemory
dludwig@8451
  1570
        );
dludwig@8451
  1571
    if (FAILED(result)) {
dludwig@8553
  1572
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result);
dludwig@8451
  1573
        textureData->stagingTexture = nullptr;
dludwig@8451
  1574
        return -1;
dludwig@8451
  1575
    }
dludwig@8451
  1576
dludwig@8451
  1577
    // Make note of where the staging texture will be written to (on a
dludwig@8451
  1578
    // call to SDL_UnlockTexture):
dludwig@8451
  1579
    textureData->lockedTexturePosition = XMINT2(rect->x, rect->y);
dludwig@8451
  1580
dludwig@8451
  1581
    // Make sure the caller has information on the texture's pixel buffer,
dludwig@8451
  1582
    // then return:
dludwig@8451
  1583
    *pixels = textureMemory.pData;
dludwig@8451
  1584
    *pitch = textureMemory.RowPitch;
dludwig@8451
  1585
    return 0;
dludwig@8451
  1586
}
dludwig@8451
  1587
dludwig@8451
  1588
static void
dludwig@8451
  1589
D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
dludwig@8451
  1590
{
dludwig@8451
  1591
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8451
  1592
    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
dludwig@8451
  1593
dludwig@8451
  1594
    // Commit the pixel buffer's changes back to the staging texture:
dludwig@8451
  1595
    rendererData->d3dContext->Unmap(
dludwig@8451
  1596
        textureData->stagingTexture.Get(),
dludwig@8451
  1597
        0);
dludwig@8451
  1598
dludwig@8451
  1599
    // Copy the staging texture's contents back to the main texture:
dludwig@8451
  1600
    rendererData->d3dContext->CopySubresourceRegion(
dludwig@8451
  1601
        textureData->mainTexture.Get(),
dludwig@8451
  1602
        D3D11CalcSubresource(0, 0, 0),
dludwig@8451
  1603
        textureData->lockedTexturePosition.x,
dludwig@8451
  1604
        textureData->lockedTexturePosition.y,
dludwig@8451
  1605
        0,
dludwig@8451
  1606
        textureData->stagingTexture.Get(),
dludwig@8451
  1607
        D3D11CalcSubresource(0, 0, 0),
dludwig@8451
  1608
        NULL);
dludwig@8451
  1609
dludwig@8451
  1610
    // Clean up and return:
dludwig@8451
  1611
    textureData->stagingTexture = nullptr;
dludwig@8451
  1612
    textureData->lockedTexturePosition = XMINT2(0, 0);
dludwig@8451
  1613
}
dludwig@8451
  1614
dludwig@8451
  1615
static int
dludwig@8459
  1616
D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
dludwig@8459
  1617
{
dludwig@8459
  1618
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8459
  1619
dludwig@8459
  1620
    if (texture == NULL) {
dludwig@8459
  1621
        rendererData->currentOffscreenRenderTargetView = nullptr;
dludwig@8459
  1622
        return 0;
dludwig@8459
  1623
    }
dludwig@8459
  1624
dludwig@8459
  1625
    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
dludwig@8459
  1626
dludwig@8459
  1627
    if (!textureData->mainTextureRenderTargetView) {
dludwig@8558
  1628
        return SDL_SetError("specified texture is not a render target");
dludwig@8459
  1629
    }
dludwig@8459
  1630
dludwig@8459
  1631
    rendererData->currentOffscreenRenderTargetView = textureData->mainTextureRenderTargetView;
dludwig@8459
  1632
dludwig@8459
  1633
    return 0;
dludwig@8548
  1634
}
dludwig@8459
  1635
dludwig@8459
  1636
static int
dludwig@8400
  1637
D3D11_UpdateViewport(SDL_Renderer * renderer)
dludwig@8400
  1638
{
dludwig@8432
  1639
    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8432
  1640
dludwig@8432
  1641
    if (renderer->viewport.w == 0 || renderer->viewport.h == 0) {
dludwig@8432
  1642
        // If the viewport is empty, assume that it is because
dludwig@8432
  1643
        // SDL_CreateRenderer is calling it, and will call it again later
dludwig@8432
  1644
        // with a non-empty viewport.
dludwig@8432
  1645
        return 0;
dludwig@8432
  1646
    }
dludwig@8432
  1647
dludwig@8548
  1648
    // Make sure the SDL viewport gets rotated to that of the physical display's orientation.
dludwig@8548
  1649
    // Keep in mind here that the Y-axis will be been inverted (from Direct3D's
dludwig@8548
  1650
    // default coordinate system) so rotations will be done in the opposite
dludwig@8548
  1651
    // direction of the DXGI_MODE_ROTATION enumeration.
dludwig@8548
  1652
    switch (D3D11_GetRotationForOrientation(data->orientation))
dludwig@8432
  1653
    {
dludwig@8548
  1654
        case DXGI_MODE_ROTATION_IDENTITY:
dludwig@8548
  1655
            XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixIdentity());
dludwig@8548
  1656
            break;
dludwig@8548
  1657
        case DXGI_MODE_ROTATION_ROTATE270:
dludwig@8548
  1658
            XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PIDIV2));
dludwig@8548
  1659
            break;
dludwig@8548
  1660
        case DXGI_MODE_ROTATION_ROTATE180:
dludwig@8548
  1661
            XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PI));
dludwig@8548
  1662
            break;
dludwig@8548
  1663
        case DXGI_MODE_ROTATION_ROTATE90:
dludwig@8510
  1664
            XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(-XM_PIDIV2));
dludwig@8432
  1665
            break;
dludwig@8432
  1666
        default:
dludwig@8556
  1667
            return SDL_SetError("An unknown DisplayOrientation is being used");
dludwig@8432
  1668
    }
dludwig@8432
  1669
dludwig@8432
  1670
    //
dludwig@8432
  1671
    // Update the view matrix
dludwig@8432
  1672
    //
dludwig@8433
  1673
    float viewportWidth = (float) renderer->viewport.w;
dludwig@8433
  1674
    float viewportHeight = (float) renderer->viewport.h;
dludwig@8433
  1675
    XMStoreFloat4x4(&data->vertexShaderConstantsData.view,
dludwig@8432
  1676
        XMMatrixMultiply(
dludwig@8433
  1677
            XMMatrixScaling(2.0f / viewportWidth, 2.0f / viewportHeight, 1.0f),
dludwig@8432
  1678
            XMMatrixMultiply(
dludwig@8432
  1679
                XMMatrixTranslation(-1, -1, 0),
dludwig@8432
  1680
                XMMatrixRotationX(XM_PI)
dludwig@8432
  1681
                )));
dludwig@8434
  1682
#if 0
dludwig@8434
  1683
    data->vertexShaderConstantsData.view = XMMatrixIdentity();
dludwig@8434
  1684
#endif
dludwig@8433
  1685
dludwig@8433
  1686
    //
dludwig@8456
  1687
    // Reset the model matrix
dludwig@8456
  1688
    //
dludwig@8456
  1689
    XMStoreFloat4x4(&data->vertexShaderConstantsData.model, XMMatrixIdentity());
dludwig@8456
  1690
dludwig@8456
  1691
    //
dludwig@8433
  1692
    // Update the Direct3D viewport, which seems to be aligned to the
dludwig@8510
  1693
    // swap buffer's coordinate space, which is always in either
dludwig@8510
  1694
    // a landscape mode, for all Windows 8/RT devices, or a portrait mode,
dludwig@8510
  1695
    // for Windows Phone devices.
dludwig@8433
  1696
    //
dludwig@8433
  1697
    SDL_FRect orientationAlignedViewport;
dludwig@8548
  1698
dludwig@8508
  1699
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
dludwig@8510
  1700
    const bool swapDimensions =
dludwig@8510
  1701
        data->orientation == DisplayOrientations::Landscape ||
dludwig@8510
  1702
        data->orientation == DisplayOrientations::LandscapeFlipped;
dludwig@8508
  1703
#else
dludwig@8433
  1704
    const bool swapDimensions =
dludwig@8433
  1705
        data->orientation == DisplayOrientations::Portrait ||
dludwig@8433
  1706
        data->orientation == DisplayOrientations::PortraitFlipped;
dludwig@8508
  1707
#endif
dludwig@8433
  1708
    if (swapDimensions) {
dludwig@8433
  1709
        orientationAlignedViewport.x = (float) renderer->viewport.y;
dludwig@8433
  1710
        orientationAlignedViewport.y = (float) renderer->viewport.x;
dludwig@8433
  1711
        orientationAlignedViewport.w = (float) renderer->viewport.h;
dludwig@8433
  1712
        orientationAlignedViewport.h = (float) renderer->viewport.w;
dludwig@8433
  1713
    } else {
dludwig@8433
  1714
        orientationAlignedViewport.x = (float) renderer->viewport.x;
dludwig@8433
  1715
        orientationAlignedViewport.y = (float) renderer->viewport.y;
dludwig@8433
  1716
        orientationAlignedViewport.w = (float) renderer->viewport.w;
dludwig@8433
  1717
        orientationAlignedViewport.h = (float) renderer->viewport.h;
dludwig@8433
  1718
    }
dludwig@8504
  1719
    // TODO, WinRT: get custom viewports working with non-Landscape modes (Portrait, PortraitFlipped, and LandscapeFlipped)
dludwig@8432
  1720
dludwig@8432
  1721
    D3D11_VIEWPORT viewport;
dludwig@8432
  1722
    memset(&viewport, 0, sizeof(viewport));
dludwig@8433
  1723
    viewport.TopLeftX = orientationAlignedViewport.x;
dludwig@8433
  1724
    viewport.TopLeftY = orientationAlignedViewport.y;
dludwig@8433
  1725
    viewport.Width = orientationAlignedViewport.w;
dludwig@8433
  1726
    viewport.Height = orientationAlignedViewport.h;
dludwig@8432
  1727
    viewport.MinDepth = 0.0f;
dludwig@8432
  1728
    viewport.MaxDepth = 1.0f;
dludwig@8432
  1729
    data->d3dContext->RSSetViewports(1, &viewport);
dludwig@8432
  1730
dludwig@8433
  1731
#if 0
dludwig@8433
  1732
    SDL_Log("%s, oav={%.0f,%.0f,%.0f,%.0f}, rend={%.0f,%.0f}\n",
dludwig@8433
  1733
        __FUNCTION__,
dludwig@8433
  1734
        orientationAlignedViewport.x,
dludwig@8433
  1735
        orientationAlignedViewport.y,
dludwig@8433
  1736
        orientationAlignedViewport.w,
dludwig@8433
  1737
        orientationAlignedViewport.h,
dludwig@8433
  1738
        data->renderTargetSize.x,
dludwig@8433
  1739
        data->renderTargetSize.y);
dludwig@8433
  1740
#endif
dludwig@8433
  1741
dludwig@8400
  1742
    return 0;
dludwig@8400
  1743
}
dludwig@8400
  1744
dludwig@8482
  1745
static int
dludwig@8482
  1746
D3D11_UpdateClipRect(SDL_Renderer * renderer)
dludwig@8482
  1747
{
dludwig@8482
  1748
    // TODO, WinRT: implement D3D11_UpdateClipRect
dludwig@8482
  1749
    return 0;
dludwig@8482
  1750
}
dludwig@8482
  1751
dludwig@8459
  1752
static ComPtr<ID3D11RenderTargetView> &
dludwig@8459
  1753
D3D11_GetCurrentRenderTargetView(SDL_Renderer * renderer)
dludwig@8459
  1754
{
dludwig@8459
  1755
    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8459
  1756
    if (data->currentOffscreenRenderTargetView) {
dludwig@8459
  1757
        return data->currentOffscreenRenderTargetView;
dludwig@8459
  1758
    } else {
dludwig@8459
  1759
        return data->mainRenderTargetView;
dludwig@8459
  1760
    }
dludwig@8459
  1761
}
dludwig@8459
  1762
dludwig@8416
  1763
static int
dludwig@8416
  1764
D3D11_RenderClear(SDL_Renderer * renderer)
dludwig@8416
  1765
{
dludwig@8416
  1766
    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8416
  1767
    const float colorRGBA[] = {
dludwig@8423
  1768
        (renderer->r / 255.0f),
dludwig@8423
  1769
        (renderer->g / 255.0f),
dludwig@8423
  1770
        (renderer->b / 255.0f),
dludwig@8423
  1771
        (renderer->a / 255.0f)
dludwig@8416
  1772
    };
dludwig@8416
  1773
    data->d3dContext->ClearRenderTargetView(
dludwig@8459
  1774
        D3D11_GetCurrentRenderTargetView(renderer).Get(),
dludwig@8416
  1775
        colorRGBA
dludwig@8416
  1776
        );
dludwig@8416
  1777
    return 0;
dludwig@8416
  1778
}
dludwig@8416
  1779
dludwig@8429
  1780
static int
dludwig@8429
  1781
D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
dludwig@8550
  1782
                         const void * vertexData, size_t dataSizeInBytes)
dludwig@8416
  1783
{
dludwig@8416
  1784
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8425
  1785
    HRESULT result = S_OK;
dludwig@8449
  1786
    D3D11_BUFFER_DESC vertexBufferDesc;
dludwig@8449
  1787
dludwig@8449
  1788
    if (rendererData->vertexBuffer) {
dludwig@8449
  1789
        rendererData->vertexBuffer->GetDesc(&vertexBufferDesc);
dludwig@8449
  1790
    } else {
dludwig@8449
  1791
        memset(&vertexBufferDesc, 0, sizeof(vertexBufferDesc));
dludwig@8449
  1792
    }
dludwig@8449
  1793
dludwig@8449
  1794
    if (vertexBufferDesc.ByteWidth >= dataSizeInBytes) {
dludwig@8550
  1795
        D3D11_MAPPED_SUBRESOURCE mappedResource;
dludwig@8550
  1796
        ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE));
dludwig@8550
  1797
        result = rendererData->d3dContext->Map(rendererData->vertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
dludwig@8550
  1798
        if (FAILED(result)) {
dludwig@8553
  1799
            WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [vertex buffer]", result);
dludwig@8550
  1800
            return -1;
dludwig@8550
  1801
        }
dludwig@8550
  1802
        memcpy(mappedResource.pData, vertexData, dataSizeInBytes);
dludwig@8550
  1803
        rendererData->d3dContext->Unmap(rendererData->vertexBuffer.Get(), 0);
dludwig@8425
  1804
    } else {
dludwig@8449
  1805
        vertexBufferDesc.ByteWidth = dataSizeInBytes;
dludwig@8550
  1806
        vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
dludwig@8449
  1807
        vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
dludwig@8550
  1808
        vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
dludwig@8449
  1809
dludwig@8425
  1810
        D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
dludwig@8429
  1811
        vertexBufferData.pSysMem = vertexData;
dludwig@8425
  1812
        vertexBufferData.SysMemPitch = 0;
dludwig@8425
  1813
        vertexBufferData.SysMemSlicePitch = 0;
dludwig@8449
  1814
dludwig@8425
  1815
        result = rendererData->d3dDevice->CreateBuffer(
dludwig@8425
  1816
            &vertexBufferDesc,
dludwig@8425
  1817
            &vertexBufferData,
dludwig@8425
  1818
            &rendererData->vertexBuffer
dludwig@8425
  1819
            );
dludwig@8425
  1820
        if (FAILED(result)) {
dludwig@8553
  1821
            WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBuffer [vertex buffer]", result);
dludwig@8425
  1822
            return -1;
dludwig@8425
  1823
        }
dludwig@8425
  1824
    }
dludwig@8425
  1825
dludwig@8416
  1826
    UINT stride = sizeof(VertexPositionColor);
dludwig@8416
  1827
    UINT offset = 0;
dludwig@8416
  1828
    rendererData->d3dContext->IASetVertexBuffers(
dludwig@8416
  1829
        0,
dludwig@8416
  1830
        1,
dludwig@8416
  1831
        rendererData->vertexBuffer.GetAddressOf(),
dludwig@8416
  1832
        &stride,
dludwig@8416
  1833
        &offset
dludwig@8429
  1834
        );
dludwig@8429
  1835
dludwig@8429
  1836
    return 0;
dludwig@8429
  1837
}
dludwig@8429
  1838
dludwig@8429
  1839
static void
dludwig@8429
  1840
D3D11_RenderStartDrawOp(SDL_Renderer * renderer)
dludwig@8429
  1841
{
dludwig@8429
  1842
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8429
  1843
dludwig@8429
  1844
    rendererData->d3dContext->OMSetRenderTargets(
dludwig@8429
  1845
        1,
dludwig@8459
  1846
        D3D11_GetCurrentRenderTargetView(renderer).GetAddressOf(),
dludwig@8429
  1847
        nullptr
dludwig@8416
  1848
        );
dludwig@8442
  1849
}
dludwig@8431
  1850
dludwig@8442
  1851
static void
dludwig@8442
  1852
D3D11_RenderSetBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
dludwig@8442
  1853
{
dludwig@8442
  1854
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8442
  1855
    switch (blendMode) {
dludwig@8431
  1856
        case SDL_BLENDMODE_BLEND:
dludwig@8431
  1857
            rendererData->d3dContext->OMSetBlendState(rendererData->blendModeBlend.Get(), 0, 0xFFFFFFFF);
dludwig@8431
  1858
            break;
dludwig@8431
  1859
        case SDL_BLENDMODE_ADD:
dludwig@8431
  1860
            rendererData->d3dContext->OMSetBlendState(rendererData->blendModeAdd.Get(), 0, 0xFFFFFFFF);
dludwig@8431
  1861
            break;
dludwig@8431
  1862
        case SDL_BLENDMODE_MOD:
dludwig@8431
  1863
            rendererData->d3dContext->OMSetBlendState(rendererData->blendModeMod.Get(), 0, 0xFFFFFFFF);
dludwig@8431
  1864
            break;
dludwig@8431
  1865
        case SDL_BLENDMODE_NONE:
dludwig@8431
  1866
            rendererData->d3dContext->OMSetBlendState(NULL, 0, 0xFFFFFFFF);
dludwig@8431
  1867
            break;
dludwig@8431
  1868
    }
dludwig@8429
  1869
}
dludwig@8429
  1870
dludwig@8429
  1871
static void
dludwig@8429
  1872
D3D11_SetPixelShader(SDL_Renderer * renderer,
dludwig@8429
  1873
                     ID3D11PixelShader * shader,
dludwig@8429
  1874
                     ID3D11ShaderResourceView * shaderResource,
dludwig@8429
  1875
                     ID3D11SamplerState * sampler)
dludwig@8429
  1876
{
dludwig@8429
  1877
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8429
  1878
    rendererData->d3dContext->PSSetShader(shader, nullptr, 0);
dludwig@8429
  1879
    rendererData->d3dContext->PSSetShaderResources(0, 1, &shaderResource);
dludwig@8429
  1880
    rendererData->d3dContext->PSSetSamplers(0, 1, &sampler);
dludwig@8429
  1881
}
dludwig@8429
  1882
dludwig@8429
  1883
static void
dludwig@8429
  1884
D3D11_RenderFinishDrawOp(SDL_Renderer * renderer,
dludwig@8449
  1885
                         D3D11_PRIMITIVE_TOPOLOGY primitiveTopology,
dludwig@8449
  1886
                         UINT vertexCount)
dludwig@8429
  1887
{
dludwig@8429
  1888
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8456
  1889
dludwig@8456
  1890
    rendererData->d3dContext->UpdateSubresource(
dludwig@8456
  1891
        rendererData->vertexShaderConstants.Get(),
dludwig@8456
  1892
        0,
dludwig@8456
  1893
        NULL,
dludwig@8456
  1894
        &rendererData->vertexShaderConstantsData,
dludwig@8456
  1895
        0,
dludwig@8456
  1896
        0
dludwig@8456
  1897
        );
dludwig@8456
  1898
dludwig@8429
  1899
    rendererData->d3dContext->IASetPrimitiveTopology(primitiveTopology);
dludwig@8429
  1900
    rendererData->d3dContext->IASetInputLayout(rendererData->inputLayout.Get());
dludwig@8429
  1901
    rendererData->d3dContext->VSSetShader(rendererData->vertexShader.Get(), nullptr, 0);
dludwig@8429
  1902
    rendererData->d3dContext->VSSetConstantBuffers(0, 1, rendererData->vertexShaderConstants.GetAddressOf());
dludwig@8429
  1903
    rendererData->d3dContext->RSSetState(rendererData->mainRasterizer.Get());
dludwig@8449
  1904
    rendererData->d3dContext->Draw(vertexCount, 0);
dludwig@8449
  1905
}
dludwig@8449
  1906
dludwig@8449
  1907
static int
dludwig@8450
  1908
D3D11_RenderDrawPoints(SDL_Renderer * renderer,
dludwig@8450
  1909
                       const SDL_FPoint * points, int count)
dludwig@8450
  1910
{
dludwig@8450
  1911
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8450
  1912
    float r, g, b, a;
dludwig@8450
  1913
dludwig@8450
  1914
    r = (float)(renderer->r / 255.0f);
dludwig@8450
  1915
    g = (float)(renderer->g / 255.0f);
dludwig@8450
  1916
    b = (float)(renderer->b / 255.0f);
dludwig@8450
  1917
    a = (float)(renderer->a / 255.0f);
dludwig@8450
  1918
dludwig@8507
  1919
    VertexPositionColor * vertices = SDL_stack_alloc(VertexPositionColor, count);
dludwig@8507
  1920
    for (int i = 0; i < min(count, 128); ++i) {
dludwig@8507
  1921
        const VertexPositionColor v = {XMFLOAT3(points[i].x, points[i].y, 0.0f),  XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)};
dludwig@8507
  1922
        vertices[i] = v;
dludwig@8450
  1923
    }
dludwig@8450
  1924
dludwig@8450
  1925
    D3D11_RenderStartDrawOp(renderer);
dludwig@8450
  1926
    D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
dludwig@8507
  1927
    if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) {
dludwig@8507
  1928
        SDL_stack_free(vertices);
dludwig@8450
  1929
        return -1;
dludwig@8450
  1930
    }
dludwig@8450
  1931
dludwig@8450
  1932
    D3D11_SetPixelShader(
dludwig@8450
  1933
        renderer,
dludwig@8450
  1934
        rendererData->colorPixelShader.Get(),
dludwig@8450
  1935
        nullptr,
dludwig@8450
  1936
        nullptr);
dludwig@8450
  1937
dludwig@8507
  1938
    D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, count);
dludwig@8507
  1939
    SDL_stack_free(vertices);
dludwig@8450
  1940
    return 0;
dludwig@8450
  1941
}
dludwig@8450
  1942
dludwig@8450
  1943
static int
dludwig@8449
  1944
D3D11_RenderDrawLines(SDL_Renderer * renderer,
dludwig@8449
  1945
                      const SDL_FPoint * points, int count)
dludwig@8449
  1946
{
dludwig@8449
  1947
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8449
  1948
    float r, g, b, a;
dludwig@8449
  1949
dludwig@8449
  1950
    r = (float)(renderer->r / 255.0f);
dludwig@8449
  1951
    g = (float)(renderer->g / 255.0f);
dludwig@8449
  1952
    b = (float)(renderer->b / 255.0f);
dludwig@8449
  1953
    a = (float)(renderer->a / 255.0f);
dludwig@8449
  1954
dludwig@8507
  1955
    VertexPositionColor * vertices = SDL_stack_alloc(VertexPositionColor, count);
dludwig@8449
  1956
    for (int i = 0; i < count; ++i) {
dludwig@8507
  1957
        const VertexPositionColor v = {XMFLOAT3(points[i].x, points[i].y, 0.0f),  XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)};
dludwig@8507
  1958
        vertices[i] = v;
dludwig@8449
  1959
    }
dludwig@8449
  1960
dludwig@8449
  1961
    D3D11_RenderStartDrawOp(renderer);
dludwig@8449
  1962
    D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
dludwig@8526
  1963
    if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) {
dludwig@8507
  1964
        SDL_stack_free(vertices);
dludwig@8449
  1965
        return -1;
dludwig@8449
  1966
    }
dludwig@8449
  1967
dludwig@8449
  1968
    D3D11_SetPixelShader(
dludwig@8449
  1969
        renderer,
dludwig@8449
  1970
        rendererData->colorPixelShader.Get(),
dludwig@8449
  1971
        nullptr,
dludwig@8449
  1972
        nullptr);
dludwig@8449
  1973
dludwig@8507
  1974
    D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, count);
dludwig@8507
  1975
    SDL_stack_free(vertices);
dludwig@8449
  1976
    return 0;
dludwig@8429
  1977
}
dludwig@8429
  1978
dludwig@8429
  1979
static int
dludwig@8429
  1980
D3D11_RenderFillRects(SDL_Renderer * renderer,
dludwig@8429
  1981
                      const SDL_FRect * rects, int count)
dludwig@8429
  1982
{
dludwig@8429
  1983
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8429
  1984
    float r, g, b, a;
dludwig@8429
  1985
dludwig@8431
  1986
    r = (float)(renderer->r / 255.0f);
dludwig@8431
  1987
    g = (float)(renderer->g / 255.0f);
dludwig@8431
  1988
    b = (float)(renderer->b / 255.0f);
dludwig@8431
  1989
    a = (float)(renderer->a / 255.0f);
dludwig@8429
  1990
dludwig@8433
  1991
#if 0
dludwig@8433
  1992
    // Set up a test pattern:
dludwig@8434
  1993
    SDL_FRect _rects[] = {
dludwig@8433
  1994
        {-1.1f, 1.1f, 1.1f, -1.1f},
dludwig@8433
  1995
        {-1.0f, 1.0f, 1.0f, -1.0f},     // red
dludwig@8433
  1996
        {0.0f, 1.0f, 1.0f, -1.0f},      // green
dludwig@8433
  1997
        {-1.0f, 0.0f, 1.0f, -1.0f},     // blue
dludwig@8433
  1998
        {0.0f, 0.0f, 1.0f, -1.0f}       // white
dludwig@8433
  1999
    };
dludwig@8434
  2000
    count = sizeof(_rects) / sizeof(SDL_FRect);
dludwig@8434
  2001
#define rects _rects
dludwig@8433
  2002
#endif
dludwig@8429
  2003
dludwig@8429
  2004
    for (int i = 0; i < count; ++i) {
dludwig@8433
  2005
        D3D11_RenderStartDrawOp(renderer);
dludwig@8442
  2006
        D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
dludwig@8433
  2007
dludwig@8433
  2008
#if 0
dludwig@8433
  2009
        // Set colors for the test pattern:
dludwig@8433
  2010
        a = 1.0f;
dludwig@8433
  2011
        switch (i) {
dludwig@8433
  2012
            case 0: r = 1.0f; g = 1.0f; b = 0.0f; break;
dludwig@8433
  2013
            case 1: r = 1.0f; g = 0.0f; b = 0.0f; break;
dludwig@8433
  2014
            case 2: r = 0.0f; g = 1.0f; b = 0.0f; break;
dludwig@8433
  2015
            case 3: r = 0.0f; g = 0.0f; b = 1.0f; break;
dludwig@8433
  2016
            case 4: r = 1.0f; g = 1.0f; b = 1.0f; break;
dludwig@8433
  2017
        }
dludwig@8433
  2018
#endif
dludwig@8433
  2019
dludwig@8429
  2020
        VertexPositionColor vertices[] = {
dludwig@8429
  2021
            {XMFLOAT3(rects[i].x, rects[i].y, 0.0f),                           XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)},
dludwig@8429
  2022
            {XMFLOAT3(rects[i].x, rects[i].y + rects[i].h, 0.0f),              XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)},
dludwig@8429
  2023
            {XMFLOAT3(rects[i].x + rects[i].w, rects[i].y, 0.0f),              XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)},
dludwig@8429
  2024
            {XMFLOAT3(rects[i].x + rects[i].w, rects[i].y + rects[i].h, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)},
dludwig@8429
  2025
        };
dludwig@8429
  2026
        if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
dludwig@8429
  2027
            return -1;
dludwig@8429
  2028
        }
dludwig@8416
  2029
dludwig@8429
  2030
        D3D11_SetPixelShader(
dludwig@8429
  2031
            renderer,
dludwig@8429
  2032
            rendererData->colorPixelShader.Get(),
dludwig@8429
  2033
            nullptr,
dludwig@8429
  2034
            nullptr);
dludwig@8416
  2035
dludwig@8449
  2036
        D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
dludwig@8429
  2037
    }
dludwig@8429
  2038
dludwig@8429
  2039
    return 0;
dludwig@8429
  2040
}
dludwig@8429
  2041
dludwig@8540
  2042
static ID3D11SamplerState *
dludwig@8540
  2043
D3D11_RenderGetSampler(SDL_Renderer * renderer, SDL_Texture * texture)
dludwig@8540
  2044
{
dludwig@8540
  2045
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8540
  2046
    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
dludwig@8540
  2047
dludwig@8540
  2048
    switch (textureData->scaleMode) {
dludwig@8540
  2049
        case SDL_D3D11_NEAREST_PIXEL_FILTER:
dludwig@8540
  2050
            return rendererData->nearestPixelSampler.Get();
dludwig@8540
  2051
        case SDL_D3D11_LINEAR_FILTER:
dludwig@8540
  2052
            return rendererData->linearSampler.Get();
dludwig@8540
  2053
        default:
dludwig@8540
  2054
            return NULL;
dludwig@8540
  2055
    }
dludwig@8540
  2056
}
dludwig@8540
  2057
dludwig@8429
  2058
static int
dludwig@8429
  2059
D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
dludwig@8429
  2060
                 const SDL_Rect * srcrect, const SDL_FRect * dstrect)
dludwig@8429
  2061
{
dludwig@8429
  2062
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8429
  2063
    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
dludwig@8429
  2064
dludwig@8429
  2065
    D3D11_RenderStartDrawOp(renderer);
dludwig@8442
  2066
    D3D11_RenderSetBlendMode(renderer, texture->blendMode);
dludwig@8448
  2067
dludwig@8448
  2068
    float minu = (float) srcrect->x / texture->w;
dludwig@8448
  2069
    float maxu = (float) (srcrect->x + srcrect->w) / texture->w;
dludwig@8448
  2070
    float minv = (float) srcrect->y / texture->h;
dludwig@8448
  2071
    float maxv = (float) (srcrect->y + srcrect->h) / texture->h;
dludwig@8458
  2072
dludwig@8458
  2073
    float r = 1.0f;
dludwig@8458
  2074
    float g = 1.0f;
dludwig@8458
  2075
    float b = 1.0f;
dludwig@8458
  2076
    float a = 1.0f;
dludwig@8458
  2077
    if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
dludwig@8458
  2078
        r = (float)(texture->r / 255.0f);
dludwig@8458
  2079
        g = (float)(texture->g / 255.0f);
dludwig@8458
  2080
        b = (float)(texture->b / 255.0f);
dludwig@8458
  2081
    }
dludwig@8458
  2082
    if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
dludwig@8458
  2083
        a = (float)(texture->a / 255.0f);
dludwig@8458
  2084
    }
dludwig@8416
  2085
dludwig@8429
  2086
    VertexPositionColor vertices[] = {
dludwig@8458
  2087
        {XMFLOAT3(dstrect->x, dstrect->y, 0.0f),                           XMFLOAT2(minu, minv), XMFLOAT4(r, g, b, a)},
dludwig@8458
  2088
        {XMFLOAT3(dstrect->x, dstrect->y + dstrect->h, 0.0f),              XMFLOAT2(minu, maxv), XMFLOAT4(r, g, b, a)},
dludwig@8458
  2089
        {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y, 0.0f),              XMFLOAT2(maxu, minv), XMFLOAT4(r, g, b, a)},
dludwig@8458
  2090
        {XMFLOAT3(dstrect->x + dstrect->w, dstrect->y + dstrect->h, 0.0f), XMFLOAT2(maxu, maxv), XMFLOAT4(r, g, b, a)},
dludwig@8429
  2091
    };
dludwig@8429
  2092
    if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
dludwig@8429
  2093
        return -1;
dludwig@8429
  2094
    }
dludwig@8418
  2095
dludwig@8540
  2096
    ID3D11SamplerState *textureSampler = D3D11_RenderGetSampler(renderer, texture);
dludwig@8429
  2097
    D3D11_SetPixelShader(
dludwig@8429
  2098
        renderer,
dludwig@8429
  2099
        rendererData->texturePixelShader.Get(),
dludwig@8429
  2100
        textureData->mainTextureResourceView.Get(),
dludwig@8540
  2101
        textureSampler);
dludwig@8416
  2102
dludwig@8449
  2103
    D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
dludwig@8416
  2104
dludwig@8416
  2105
    return 0;
dludwig@8416
  2106
}
dludwig@8416
  2107
dludwig@8454
  2108
static int
dludwig@8455
  2109
D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
dludwig@8455
  2110
                   const SDL_Rect * srcrect, const SDL_FRect * dstrect,
dludwig@8455
  2111
                   const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip)
dludwig@8455
  2112
{
dludwig@8455
  2113
    D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
dludwig@8455
  2114
    D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
dludwig@8455
  2115
dludwig@8455
  2116
    D3D11_RenderStartDrawOp(renderer);
dludwig@8455
  2117
    D3D11_RenderSetBlendMode(renderer, texture->blendMode);
dludwig@8455
  2118
dludwig@8455
  2119
    float minu = (float) srcrect->x / texture->w;
dludwig@8455
  2120
    float maxu = (float) (srcrect->x + srcrect->w) / texture->w;
dludwig@8455
  2121
    float minv = (float) srcrect->y / texture->h;
dludwig@8455
  2122
    float maxv = (float) (srcrect->y + srcrect->h) / texture->h;
dludwig@8455
  2123
dludwig@8458
  2124
    float r = 1.0f;
dludwig@8458
  2125
    float g = 1.0f;
dludwig@8458
  2126
    float b = 1.0f;
dludwig@8458
  2127
    float a = 1.0f;
dludwig@8458
  2128
    if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
dludwig@8458
  2129
        r = (float)(texture->r / 255.0f);
dludwig@8458
  2130
        g = (float)(texture->g / 255.0f);
dludwig@8458
  2131
        b = (float)(texture->b / 255.0f);
dludwig@8458
  2132
    }
dludwig@8458
  2133
    if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
dludwig@8458
  2134
        a = (float)(texture->a / 255.0f);
dludwig@8458
  2135
    }
dludwig@8458
  2136
dludwig@8455
  2137
    if (flip & SDL_FLIP_HORIZONTAL) {
dludwig@8455
  2138
        float tmp = maxu;
dludwig@8455
  2139
        maxu = minu;
dludwig@8455
  2140
        minu = tmp;
dludwig@8455
  2141
    }
dludwig@8455
  2142
    if (flip & SDL_FLIP_VERTICAL) {
dludwig@8455
  2143
        float tmp = maxv;
dludwig@8455
  2144
        maxv = minv;
dludwig@8455
  2145
        minv = tmp;
dludwig@8455
  2146
    }
dludwig@8456
  2147
dludwig@8456
  2148
    XMFLOAT4X4 oldModelMatrix = rendererData->vertexShaderConstantsData.model;
dludwig@8456
  2149
    XMStoreFloat4x4(
dludwig@8456
  2150
        &rendererData->vertexShaderConstantsData.model,
dludwig@8456
  2151
        XMMatrixMultiply(
dludwig@8456
  2152
            XMMatrixRotationZ((float)(XM_PI * (float) angle / 180.0f)),
dludwig@8456
  2153
            XMMatrixTranslation(dstrect->x + center->x, dstrect->y + center->y, 0)
dludwig@8456
  2154
            ));
dludwig@8456
  2155
dludwig@8456
  2156
    const float minx = -center->x;
dludwig@8456
  2157
    const float maxx = dstrect->w - center->x;
dludwig@8456
  2158
    const float miny = -center->y;
dludwig@8456
  2159
    const float maxy = dstrect->h - center->y;
dludwig@8455
  2160
dludwig@8455
  2161
    VertexPositionColor vertices[] = {
dludwig@8458
  2162
        {XMFLOAT3(minx, miny, 0.0f), XMFLOAT2(minu, minv), XMFLOAT4(r, g, b, a)},
dludwig@8458
  2163
        {XMFLOAT3(minx, maxy, 0.0f), XMFLOAT2(minu, maxv), XMFLOAT4(r, g, b, a)},
dludwig@8458
  2164
        {XMFLOAT3(maxx, miny, 0.0f), XMFLOAT2(maxu, minv), XMFLOAT4(r, g, b, a)},
dludwig@8458
  2165
        {XMFLOAT3(maxx, maxy, 0.0f), XMFLOAT2(maxu, maxv), XMFLOAT4(r, g, b, a)},
dludwig@8455
  2166
    };
dludwig@8455
  2167
    if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
dludwig@8455
  2168
        return -1;
dludwig@8455
  2169
    }
dludwig@8455
  2170
dludwig@8540
  2171
    ID3D11SamplerState *textureSampler = D3D11_RenderGetSampler(renderer, texture);
dludwig@8455
  2172
    D3D11_SetPixelShader(
dludwig@8455
  2173
        renderer,
dludwig@8455
  2174
        rendererData->texturePixelShader.Get(),
dludwig@8455
  2175
        textureData->mainTextureResourceView.Get(),
dludwig@8540
  2176
        textureSampler);
dludwig@8455
  2177
dludwig@8455
  2178
    D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
dludwig@8456
  2179
dludwig@8456
  2180
    rendererData->vertexShaderConstantsData.model = oldModelMatrix;
dludwig@8455
  2181
dludwig@8455
  2182
    return 0;
dludwig@8455
  2183
}
dludwig@8455
  2184
dludwig@8455
  2185
static int
dludwig@8454
  2186
D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
dludwig@8454
  2187
                       Uint32 format, void * pixels, int pitch)
dludwig@8454
  2188
{
dludwig@8454
  2189
    D3D11_RenderData * data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8454
  2190
    HRESULT result = S_OK;
dludwig@8454
  2191
dludwig@8454
  2192
    // Retrieve a pointer to the back buffer:
dludwig@8454
  2193
    ComPtr<ID3D11Texture2D> backBuffer;
dludwig@8454
  2194
    result = data->swapChain->GetBuffer(
dludwig@8454
  2195
        0,
dludwig@8454
  2196
        __uuidof(ID3D11Texture2D),
dludwig@8454
  2197
        &backBuffer
dludwig@8454
  2198
        );
dludwig@8454
  2199
    if (FAILED(result)) {
dludwig@8553
  2200
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::GetBuffer [get back buffer]", result);
dludwig@8454
  2201
        return -1;
dludwig@8454
  2202
    }
dludwig@8454
  2203
dludwig@8454
  2204
    // Create a staging texture to copy the screen's data to:
dludwig@8454
  2205
    ComPtr<ID3D11Texture2D> stagingTexture;
dludwig@8454
  2206
    D3D11_TEXTURE2D_DESC stagingTextureDesc;
dludwig@8454
  2207
    backBuffer->GetDesc(&stagingTextureDesc);
dludwig@8454
  2208
    stagingTextureDesc.Width = rect->w;
dludwig@8454
  2209
    stagingTextureDesc.Height = rect->h;
dludwig@8454
  2210
    stagingTextureDesc.BindFlags = 0;
dludwig@8454
  2211
    stagingTextureDesc.MiscFlags = 0;
dludwig@8454
  2212
    stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
dludwig@8454
  2213
    stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
dludwig@8454
  2214
    result = data->d3dDevice->CreateTexture2D(
dludwig@8454
  2215
        &stagingTextureDesc,
dludwig@8454
  2216
        NULL,
dludwig@8454
  2217
        &stagingTexture);
dludwig@8454
  2218
    if (FAILED(result)) {
dludwig@8553
  2219
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result);
dludwig@8454
  2220
        return -1;
dludwig@8454
  2221
    }
dludwig@8454
  2222
dludwig@8454
  2223
    // Copy the desired portion of the back buffer to the staging texture:
dludwig@8454
  2224
    D3D11_BOX srcBox;
dludwig@8548
  2225
    switch (D3D11_GetRotationForOrientation(data->orientation)) {
dludwig@8548
  2226
        case DXGI_MODE_ROTATION_IDENTITY:
dludwig@8548
  2227
            srcBox.left = rect->x;
dludwig@8548
  2228
            srcBox.right = rect->x + rect->w;
dludwig@8548
  2229
            srcBox.top = rect->y;
dludwig@8548
  2230
            srcBox.bottom = rect->y + rect->h;
dludwig@8548
  2231
            break;
dludwig@8548
  2232
        case DXGI_MODE_ROTATION_ROTATE270:
dludwig@8548
  2233
            srcBox.left = rect->y;
dludwig@8548
  2234
            srcBox.right = rect->y + rect->h;
dludwig@8548
  2235
            srcBox.top = renderer->viewport.w - rect->x - rect->w;
dludwig@8548
  2236
            srcBox.bottom = renderer->viewport.w - rect->x;
dludwig@8548
  2237
            break;
dludwig@8548
  2238
        case DXGI_MODE_ROTATION_ROTATE180:
dludwig@8548
  2239
            srcBox.left = renderer->viewport.w - rect->x - rect->w;
dludwig@8548
  2240
            srcBox.right = renderer->viewport.w - rect->x;
dludwig@8548
  2241
            srcBox.top = renderer->viewport.h - rect->y - rect->h;
dludwig@8548
  2242
            srcBox.bottom = renderer->viewport.h - rect->y;
dludwig@8548
  2243
            break;
dludwig@8548
  2244
        case DXGI_MODE_ROTATION_ROTATE90:
dludwig@8548
  2245
            srcBox.left = renderer->viewport.h - rect->y - rect->h;
dludwig@8548
  2246
            srcBox.right = renderer->viewport.h - rect->y;
dludwig@8548
  2247
            srcBox.top = rect->x;
dludwig@8548
  2248
            srcBox.bottom = rect->x + rect->h;
dludwig@8548
  2249
            break;
dludwig@8548
  2250
        default:
dludwig@8548
  2251
            return SDL_SetError("The physical display is in an unknown or unsupported orientation");
dludwig@8548
  2252
    }
dludwig@8454
  2253
    srcBox.front = 0;
dludwig@8454
  2254
    srcBox.back = 1;
dludwig@8454
  2255
    data->d3dContext->CopySubresourceRegion(
dludwig@8454
  2256
        stagingTexture.Get(),
dludwig@8454
  2257
        D3D11CalcSubresource(0, 0, 0),
dludwig@8454
  2258
        0, 0, 0,
dludwig@8454
  2259
        backBuffer.Get(),
dludwig@8454
  2260
        D3D11CalcSubresource(0, 0, 0),
dludwig@8454
  2261
        &srcBox);
dludwig@8454
  2262
dludwig@8454
  2263
    // Map the staging texture's data to CPU-accessible memory:
dludwig@8454
  2264
    D3D11_MAPPED_SUBRESOURCE textureMemory = {0};
dludwig@8454
  2265
    result = data->d3dContext->Map(
dludwig@8454
  2266
        stagingTexture.Get(),
dludwig@8454
  2267
        D3D11CalcSubresource(0, 0, 0),
dludwig@8454
  2268
        D3D11_MAP_READ,
dludwig@8454
  2269
        0,
dludwig@8454
  2270
        &textureMemory);
dludwig@8454
  2271
    if (FAILED(result)) {
dludwig@8553
  2272
        WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result);
dludwig@8454
  2273
        return -1;
dludwig@8454
  2274
    }
dludwig@8454
  2275
dludwig@8454
  2276
    // Copy the data into the desired buffer, converting pixels to the
dludwig@8454
  2277
    // desired format at the same time:
dludwig@8454
  2278
    if (SDL_ConvertPixels(
dludwig@8454
  2279
        rect->w, rect->h,
dludwig@8454
  2280
        DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format),
dludwig@8454
  2281
        textureMemory.pData,
dludwig@8454
  2282
        textureMemory.RowPitch,
dludwig@8454
  2283
        format,
dludwig@8454
  2284
        pixels,
dludwig@8454
  2285
        pitch) != 0)
dludwig@8454
  2286
    {
dludwig@8454
  2287
        // When SDL_ConvertPixels fails, it'll have already set the format.
dludwig@8454
  2288
        // Get the error message, and attach some extra data to it.
dludwig@8454
  2289
        std::string errorMessage = string(__FUNCTION__ ", Convert Pixels failed: ") + SDL_GetError();
dludwig@8556
  2290
        return SDL_SetError(errorMessage.c_str());
dludwig@8454
  2291
    }
dludwig@8454
  2292
dludwig@8454
  2293
    // Unmap the texture:
dludwig@8454
  2294
    data->d3dContext->Unmap(
dludwig@8454
  2295
        stagingTexture.Get(),
dludwig@8454
  2296
        D3D11CalcSubresource(0, 0, 0));
dludwig@8454
  2297
dludwig@8454
  2298
    // All done.  The staging texture will be cleaned up in it's container
dludwig@8454
  2299
    // ComPtr<>'s destructor.
dludwig@8454
  2300
    return 0;
dludwig@8454
  2301
}
dludwig@8454
  2302
dludwig@8401
  2303
static void
dludwig@8401
  2304
D3D11_RenderPresent(SDL_Renderer * renderer)
dludwig@8401
  2305
{
dludwig@8401
  2306
    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8401
  2307
dludwig@8401
  2308
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
dludwig@8401
  2309
    // The first argument instructs DXGI to block until VSync, putting the application
dludwig@8401
  2310
    // to sleep until the next VSync. This ensures we don't waste any cycles rendering
dludwig@8401
  2311
    // frames that will never be displayed to the screen.
dludwig@8401
  2312
    HRESULT hr = data->swapChain->Present(1, 0);
dludwig@8401
  2313
#else
dludwig@8401
  2314
    // The application may optionally specify "dirty" or "scroll"
dludwig@8401
  2315
    // rects to improve efficiency in certain scenarios.
dludwig@8401
  2316
    // This option is not available on Windows Phone 8, to note.
dludwig@8401
  2317
    DXGI_PRESENT_PARAMETERS parameters = {0};
dludwig@8401
  2318
    parameters.DirtyRectsCount = 0;
dludwig@8401
  2319
    parameters.pDirtyRects = nullptr;
dludwig@8401
  2320
    parameters.pScrollRect = nullptr;
dludwig@8401
  2321
    parameters.pScrollOffset = nullptr;
dludwig@8401
  2322
    
dludwig@8401
  2323
    // The first argument instructs DXGI to block until VSync, putting the application
dludwig@8401
  2324
    // to sleep until the next VSync. This ensures we don't waste any cycles rendering
dludwig@8401
  2325
    // frames that will never be displayed to the screen.
dludwig@8401
  2326
    HRESULT hr = data->swapChain->Present1(1, 0, &parameters);
dludwig@8401
  2327
#endif
dludwig@8401
  2328
dludwig@8401
  2329
    // Discard the contents of the render target.
dludwig@8401
  2330
    // This is a valid operation only when the existing contents will be entirely
dludwig@8401
  2331
    // overwritten. If dirty or scroll rects are used, this call should be removed.
dludwig@8459
  2332
    data->d3dContext->DiscardView(data->mainRenderTargetView.Get());
dludwig@8401
  2333
dludwig@8401
  2334
    // If the device was removed either by a disconnect or a driver upgrade, we 
dludwig@8401
  2335
    // must recreate all device resources.
dludwig@8414
  2336
    //
dludwig@8414
  2337
    // TODO, WinRT: consider throwing an exception if D3D11_RenderPresent fails, especially if there is a way to salvedge debug info from users' machines
dludwig@8401
  2338
    if (hr == DXGI_ERROR_DEVICE_REMOVED)
dludwig@8401
  2339
    {
dludwig@8414
  2340
        hr = D3D11_HandleDeviceLost(renderer);
dludwig@8414
  2341
        if (FAILED(hr)) {
dludwig@8554
  2342
            /* D3D11_HandleDeviceLost will set the SDL error */
dludwig@8414
  2343
        }
dludwig@8401
  2344
    }
dludwig@8401
  2345
    else