src/render/direct3d11/SDL_render_d3d11.cpp
author David Ludwig <dludwig@pobox.com>
Sat, 09 Feb 2013 11:42:17 -0500
changeset 8410 ba725b3a0c87
parent 8401 29ecd2eca4af
child 8412 59f1191a5cca
permissions -rw-r--r--
WinRT: more code-moving from SDL_winrtrenderer* to SDL_render_d3d11*
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@8400
    26
extern "C" {
dludwig@8400
    27
#include "../../core/windows/SDL_windows.h"
dludwig@8400
    28
//#include "SDL_hints.h"
dludwig@8400
    29
//#include "SDL_loadso.h"
dludwig@8410
    30
#include "SDL_system.h"
dludwig@8400
    31
#include "SDL_syswm.h"
dludwig@8400
    32
#include "../SDL_sysrender.h"
dludwig@8400
    33
//#include "stdio.h"
dludwig@8400
    34
}
dludwig@8400
    35
dludwig@8410
    36
#include <fstream>
dludwig@8410
    37
#include <string>
dludwig@8410
    38
#include <vector>
dludwig@8410
    39
dludwig@8400
    40
#include "SDL_render_d3d11_cpp.h"
dludwig@8400
    41
dludwig@8410
    42
using namespace DirectX;
dludwig@8410
    43
using namespace Microsoft::WRL;
dludwig@8410
    44
using namespace std;
dludwig@8410
    45
dludwig@8410
    46
/* Direct3D 11.1 renderer implementation */
dludwig@8400
    47
dludwig@8400
    48
static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags);
dludwig@8400
    49
//static void D3D11_WindowEvent(SDL_Renderer * renderer,
dludwig@8400
    50
//                            const SDL_WindowEvent *event);
dludwig@8400
    51
//static int D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
dludwig@8400
    52
//static int D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
dludwig@8400
    53
//                             const SDL_Rect * rect, const void *pixels,
dludwig@8400
    54
//                             int pitch);
dludwig@8400
    55
//static int D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
dludwig@8400
    56
//                           const SDL_Rect * rect, void **pixels, int *pitch);
dludwig@8400
    57
//static void D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
dludwig@8400
    58
//static int D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
dludwig@8400
    59
static int D3D11_UpdateViewport(SDL_Renderer * renderer);
dludwig@8400
    60
//static int D3D11_RenderClear(SDL_Renderer * renderer);
dludwig@8400
    61
//static int D3D11_RenderDrawPoints(SDL_Renderer * renderer,
dludwig@8400
    62
//                                const SDL_FPoint * points, int count);
dludwig@8400
    63
//static int D3D11_RenderDrawLines(SDL_Renderer * renderer,
dludwig@8400
    64
//                               const SDL_FPoint * points, int count);
dludwig@8400
    65
//static int D3D11_RenderFillRects(SDL_Renderer * renderer,
dludwig@8400
    66
//                               const SDL_FRect * rects, int count);
dludwig@8400
    67
//static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
dludwig@8400
    68
//                          const SDL_Rect * srcrect, const SDL_FRect * dstrect);
dludwig@8400
    69
//static int D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
dludwig@8400
    70
//                          const SDL_Rect * srcrect, const SDL_FRect * dstrect,
dludwig@8400
    71
//                          const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip);
dludwig@8400
    72
//static int D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
dludwig@8400
    73
//                                Uint32 format, void * pixels, int pitch);
dludwig@8401
    74
static void D3D11_RenderPresent(SDL_Renderer * renderer);
dludwig@8400
    75
//static void D3D11_DestroyTexture(SDL_Renderer * renderer,
dludwig@8400
    76
//                               SDL_Texture * texture);
dludwig@8400
    77
//static void D3D11_DestroyRenderer(SDL_Renderer * renderer);
dludwig@8400
    78
dludwig@8410
    79
/* Direct3D 11.1 Internal Functions */
dludwig@8410
    80
HRESULT WINRT_CreateDeviceResources(SDL_Renderer * renderer);
dludwig@8410
    81
dludwig@8400
    82
dludwig@8400
    83
extern "C" {
dludwig@8400
    84
    SDL_RenderDriver D3D11_RenderDriver = {
dludwig@8400
    85
    D3D11_CreateRenderer,
dludwig@8400
    86
    {
dludwig@8400
    87
     "direct3d",
dludwig@8400
    88
     (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
dludwig@8400
    89
     1,
dludwig@8400
    90
     {SDL_PIXELFORMAT_ARGB8888},
dludwig@8400
    91
     0,
dludwig@8400
    92
     0}
dludwig@8400
    93
    };
dludwig@8400
    94
}
dludwig@8400
    95
dludwig@8400
    96
//typedef struct
dludwig@8400
    97
//{
dludwig@8400
    98
//    float x, y, z;
dludwig@8400
    99
//    DWORD color;
dludwig@8400
   100
//    float u, v;
dludwig@8400
   101
//} Vertex;
dludwig@8400
   102
dludwig@8400
   103
SDL_Renderer *
dludwig@8400
   104
D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
dludwig@8400
   105
{
dludwig@8400
   106
    SDL_Renderer *renderer;
dludwig@8400
   107
    D3D11_RenderData *data;
dludwig@8400
   108
//    SDL_SysWMinfo windowinfo;
dludwig@8400
   109
 //   HRESULT result;
dludwig@8400
   110
 //   D3DPRESENT_PARAMETERS pparams;
dludwig@8400
   111
 //   IDirect3DSwapChain9 *chain;
dludwig@8400
   112
 //   D3DCAPS9 caps;
dludwig@8400
   113
 //   Uint32 window_flags;
dludwig@8400
   114
 //   int w, h;
dludwig@8400
   115
 //   SDL_DisplayMode fullscreen_mode;
dludwig@8400
   116
 //   D3DMATRIX matrix;
dludwig@8400
   117
 //   int d3dxVersion;
dludwig@8400
   118
	//char d3dxDLLFile[50];
dludwig@8400
   119
dludwig@8400
   120
    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
dludwig@8400
   121
    if (!renderer) {
dludwig@8400
   122
        SDL_OutOfMemory();
dludwig@8400
   123
        return NULL;
dludwig@8400
   124
    }
dludwig@8400
   125
    SDL_zerop(renderer);
dludwig@8400
   126
dludwig@8400
   127
    data = new D3D11_RenderData;    // Use the C++ 'new' operator to make sure the struct's members initialize using C++ rules
dludwig@8400
   128
    if (!data) {
dludwig@8400
   129
        SDL_OutOfMemory();
dludwig@8400
   130
        return NULL;
dludwig@8400
   131
    }
dludwig@8410
   132
    data->featureLevel = (D3D_FEATURE_LEVEL) 0;
dludwig@8410
   133
    data->vertexCount = 0;
dludwig@8410
   134
    data->loadingComplete = false;
dludwig@8400
   135
dludwig@8400
   136
    // TODO: Create Direct3D Object(s)
dludwig@8400
   137
dludwig@8400
   138
    //renderer->WindowEvent = D3D11_WindowEvent;
dludwig@8400
   139
    //renderer->CreateTexture = D3D11_CreateTexture;
dludwig@8400
   140
    //renderer->UpdateTexture = D3D11_UpdateTexture;
dludwig@8400
   141
    //renderer->LockTexture = D3D11_LockTexture;
dludwig@8400
   142
    //renderer->UnlockTexture = D3D11_UnlockTexture;
dludwig@8400
   143
    //renderer->SetRenderTarget = D3D11_SetRenderTarget;
dludwig@8400
   144
    renderer->UpdateViewport = D3D11_UpdateViewport;
dludwig@8400
   145
    //renderer->RenderClear = D3D11_RenderClear;
dludwig@8400
   146
    //renderer->RenderDrawPoints = D3D11_RenderDrawPoints;
dludwig@8400
   147
    //renderer->RenderDrawLines = D3D11_RenderDrawLines;
dludwig@8400
   148
    //renderer->RenderFillRects = D3D11_RenderFillRects;
dludwig@8400
   149
    //renderer->RenderCopy = D3D11_RenderCopy;
dludwig@8400
   150
    //renderer->RenderCopyEx = D3D11_RenderCopyEx;
dludwig@8400
   151
    //renderer->RenderReadPixels = D3D11_RenderReadPixels;
dludwig@8401
   152
    renderer->RenderPresent = D3D11_RenderPresent;
dludwig@8400
   153
    //renderer->DestroyTexture = D3D11_DestroyTexture;
dludwig@8400
   154
    //renderer->DestroyRenderer = D3D11_DestroyRenderer;
dludwig@8400
   155
    renderer->info = D3D11_RenderDriver.info;
dludwig@8400
   156
    renderer->driverdata = data;
dludwig@8400
   157
dludwig@8400
   158
    renderer->info.flags = SDL_RENDERER_ACCELERATED;
dludwig@8400
   159
dludwig@8400
   160
    //SDL_VERSION(&windowinfo.version);
dludwig@8400
   161
    //SDL_GetWindowWMInfo(window, &windowinfo);
dludwig@8400
   162
dludwig@8400
   163
    //window_flags = SDL_GetWindowFlags(window);
dludwig@8400
   164
    //SDL_GetWindowSize(window, &w, &h);
dludwig@8400
   165
    //SDL_GetWindowDisplayMode(window, &fullscreen_mode);
dludwig@8400
   166
dludwig@8400
   167
    //SDL_zero(pparams);
dludwig@8400
   168
    //pparams.hDeviceWindow = windowinfo.info.win.window;
dludwig@8400
   169
    //pparams.BackBufferWidth = w;
dludwig@8400
   170
    //pparams.BackBufferHeight = h;
dludwig@8400
   171
    //if (window_flags & SDL_WINDOW_FULLSCREEN) {
dludwig@8400
   172
    //    pparams.BackBufferFormat =
dludwig@8400
   173
    //        PixelFormatToD3DFMT(fullscreen_mode.format);
dludwig@8400
   174
    //} else {
dludwig@8400
   175
    //    pparams.BackBufferFormat = D3DFMT_UNKNOWN;
dludwig@8400
   176
    //}
dludwig@8400
   177
    //pparams.BackBufferCount = 1;
dludwig@8400
   178
    //pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
dludwig@8400
   179
dludwig@8400
   180
    //if (window_flags & SDL_WINDOW_FULLSCREEN) {
dludwig@8400
   181
    //    pparams.Windowed = FALSE;
dludwig@8400
   182
    //    pparams.FullScreen_RefreshRateInHz =
dludwig@8400
   183
    //        fullscreen_mode.refresh_rate;
dludwig@8400
   184
    //} else {
dludwig@8400
   185
    //    pparams.Windowed = TRUE;
dludwig@8400
   186
    //    pparams.FullScreen_RefreshRateInHz = 0;
dludwig@8400
   187
    //}
dludwig@8400
   188
    //if (flags & SDL_RENDERER_PRESENTVSYNC) {
dludwig@8400
   189
    //    pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
dludwig@8400
   190
    //} else {
dludwig@8400
   191
    //    pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
dludwig@8400
   192
    //}
dludwig@8400
   193
dludwig@8400
   194
    ///* FIXME: Which adapter? */
dludwig@8400
   195
    //data->adapter = D3DADAPTER_DEFAULT;
dludwig@8400
   196
    //IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps);
dludwig@8400
   197
dludwig@8400
   198
    //result = IDirect3D9_CreateDevice(data->d3d, data->adapter,
dludwig@8400
   199
    //                                 D3DDEVTYPE_HAL,
dludwig@8400
   200
    //                                 pparams.hDeviceWindow,
dludwig@8400
   201
    //                                 D3DCREATE_FPU_PRESERVE | ((caps.
dludwig@8400
   202
    //                                  DevCaps &
dludwig@8400
   203
    //                                  D3DDEVCAPS_HWTRANSFORMANDLIGHT) ?
dludwig@8400
   204
    //                                 D3DCREATE_HARDWARE_VERTEXPROCESSING :
dludwig@8400
   205
    //                                 D3DCREATE_SOFTWARE_VERTEXPROCESSING),
dludwig@8400
   206
    //                                 &pparams, &data->device);
dludwig@8400
   207
    //if (FAILED(result)) {
dludwig@8400
   208
    //    D3D11_DestroyRenderer(renderer);
dludwig@8400
   209
    //    D3D11_SetError("CreateDevice()", result);
dludwig@8400
   210
    //    return NULL;
dludwig@8400
   211
    //}
dludwig@8400
   212
    //data->beginScene = SDL_TRUE;
dludwig@8400
   213
    //data->scaleMode = D3DTEXF_FORCE_DWORD;
dludwig@8400
   214
dludwig@8400
   215
    ///* Get presentation parameters to fill info */
dludwig@8400
   216
    //result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
dludwig@8400
   217
    //if (FAILED(result)) {
dludwig@8400
   218
    //    D3D11_DestroyRenderer(renderer);
dludwig@8400
   219
    //    D3D11_SetError("GetSwapChain()", result);
dludwig@8400
   220
    //    return NULL;
dludwig@8400
   221
    //}
dludwig@8400
   222
    //result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams);
dludwig@8400
   223
    //if (FAILED(result)) {
dludwig@8400
   224
    //    IDirect3DSwapChain9_Release(chain);
dludwig@8400
   225
    //    D3D11_DestroyRenderer(renderer);
dludwig@8400
   226
    //    D3D11_SetError("GetPresentParameters()", result);
dludwig@8400
   227
    //    return NULL;
dludwig@8400
   228
    //}
dludwig@8400
   229
    //IDirect3DSwapChain9_Release(chain);
dludwig@8400
   230
    //if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
dludwig@8400
   231
    //    renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
dludwig@8400
   232
    //}
dludwig@8400
   233
    //data->pparams = pparams;
dludwig@8400
   234
dludwig@8400
   235
    //IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
dludwig@8400
   236
    //renderer->info.max_texture_width = caps.MaxTextureWidth;
dludwig@8400
   237
    //renderer->info.max_texture_height = caps.MaxTextureHeight;
dludwig@8400
   238
    //if (caps.NumSimultaneousRTs >= 2) {
dludwig@8400
   239
    //    renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
dludwig@8400
   240
    //}
dludwig@8400
   241
dludwig@8400
   242
    ///* Set up parameters for rendering */
dludwig@8400
   243
    //IDirect3DDevice9_SetVertexShader(data->device, NULL);
dludwig@8400
   244
    //IDirect3DDevice9_SetFVF(data->device,
dludwig@8400
   245
    //                        D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
dludwig@8400
   246
    //IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE);
dludwig@8400
   247
    //IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
dludwig@8400
   248
    //                                D3DCULL_NONE);
dludwig@8400
   249
    //IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
dludwig@8400
   250
    ///* Enable color modulation by diffuse color */
dludwig@8400
   251
    //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP,
dludwig@8400
   252
    //                                      D3DTOP_MODULATE);
dludwig@8400
   253
    //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1,
dludwig@8400
   254
    //                                      D3DTA_TEXTURE);
dludwig@8400
   255
    //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2,
dludwig@8400
   256
    //                                      D3DTA_DIFFUSE);
dludwig@8400
   257
    ///* Enable alpha modulation by diffuse alpha */
dludwig@8400
   258
    //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP,
dludwig@8400
   259
    //                                      D3DTOP_MODULATE);
dludwig@8400
   260
    //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1,
dludwig@8400
   261
    //                                      D3DTA_TEXTURE);
dludwig@8400
   262
    //IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2,
dludwig@8400
   263
    //                                      D3DTA_DIFFUSE);
dludwig@8400
   264
    ///* Disable second texture stage, since we're done */
dludwig@8400
   265
    //IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP,
dludwig@8400
   266
    //                                      D3DTOP_DISABLE);
dludwig@8400
   267
    //IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP,
dludwig@8400
   268
    //                                      D3DTOP_DISABLE);
dludwig@8400
   269
dludwig@8400
   270
    ///* Store the default render target */
dludwig@8400
   271
    //IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget );
dludwig@8400
   272
    //data->currentRenderTarget = NULL;
dludwig@8400
   273
dludwig@8400
   274
    ///* Set an identity world and view matrix */
dludwig@8400
   275
    //matrix.m[0][0] = 1.0f;
dludwig@8400
   276
    //matrix.m[0][1] = 0.0f;
dludwig@8400
   277
    //matrix.m[0][2] = 0.0f;
dludwig@8400
   278
    //matrix.m[0][3] = 0.0f;
dludwig@8400
   279
    //matrix.m[1][0] = 0.0f;
dludwig@8400
   280
    //matrix.m[1][1] = 1.0f;
dludwig@8400
   281
    //matrix.m[1][2] = 0.0f;
dludwig@8400
   282
    //matrix.m[1][3] = 0.0f;
dludwig@8400
   283
    //matrix.m[2][0] = 0.0f;
dludwig@8400
   284
    //matrix.m[2][1] = 0.0f;
dludwig@8400
   285
    //matrix.m[2][2] = 1.0f;
dludwig@8400
   286
    //matrix.m[2][3] = 0.0f;
dludwig@8400
   287
    //matrix.m[3][0] = 0.0f;
dludwig@8400
   288
    //matrix.m[3][1] = 0.0f;
dludwig@8400
   289
    //matrix.m[3][2] = 0.0f;
dludwig@8400
   290
    //matrix.m[3][3] = 1.0f;
dludwig@8400
   291
    //IDirect3DDevice9_SetTransform(data->device, D3DTS_WORLD, &matrix);
dludwig@8400
   292
    //IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, &matrix);
dludwig@8400
   293
dludwig@8400
   294
    return renderer;
dludwig@8400
   295
}
dludwig@8400
   296
dludwig@8410
   297
static bool
dludwig@8410
   298
D3D11_ReadFileContents(const wstring & fileName, vector<char> & out)
dludwig@8410
   299
{
dludwig@8410
   300
    ifstream in(fileName, ios::in | ios::binary);
dludwig@8410
   301
    if (!in) {
dludwig@8410
   302
        return false;
dludwig@8410
   303
    }
dludwig@8410
   304
dludwig@8410
   305
    in.seekg(0, ios::end);
dludwig@8410
   306
    out.resize((size_t) in.tellg());
dludwig@8410
   307
    in.seekg(0, ios::beg);
dludwig@8410
   308
    in.read(&out[0], out.size());
dludwig@8410
   309
    return in.good();
dludwig@8410
   310
}
dludwig@8410
   311
dludwig@8410
   312
static bool
dludwig@8410
   313
D3D11_ReadShaderContents(const wstring & shaderName, vector<char> & out)
dludwig@8410
   314
{
dludwig@8410
   315
    wstring fileName;
dludwig@8410
   316
dludwig@8410
   317
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
dludwig@8410
   318
    fileName = SDL_WinRTGetInstalledLocationPath();
dludwig@8410
   319
    fileName += L"\\SDL_VS2012_WinRT\\";
dludwig@8410
   320
#elif WINAPI_FAMILY == WINAPI_PHONE_APP
dludwig@8410
   321
    fileName = SDL_WinRTGetInstalledLocationPath();
dludwig@8410
   322
    fileName += L"\\";
dludwig@8410
   323
#endif
dludwig@8410
   324
    // WinRT, TODO: test Direct3D 11.1 shader loading on Win32
dludwig@8410
   325
    fileName += shaderName;
dludwig@8410
   326
    return D3D11_ReadFileContents(fileName, out);
dludwig@8410
   327
}
dludwig@8410
   328
dludwig@8410
   329
HRESULT
dludwig@8410
   330
WINRT_CreateDeviceResources(SDL_Renderer * renderer)
dludwig@8410
   331
{
dludwig@8410
   332
    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8410
   333
dludwig@8410
   334
    // This flag adds support for surfaces with a different color channel ordering
dludwig@8410
   335
    // than the API default. It is required for compatibility with Direct2D.
dludwig@8410
   336
    UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
dludwig@8410
   337
dludwig@8410
   338
#if defined(_DEBUG)
dludwig@8410
   339
    // If the project is in a debug build, enable debugging via SDK Layers with this flag.
dludwig@8410
   340
    creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
dludwig@8410
   341
#endif
dludwig@8410
   342
dludwig@8410
   343
    // This array defines the set of DirectX hardware feature levels this app will support.
dludwig@8410
   344
    // Note the ordering should be preserved.
dludwig@8410
   345
    // Don't forget to declare your application's minimum required feature level in its
dludwig@8410
   346
    // description.  All applications are assumed to support 9.1 unless otherwise stated.
dludwig@8410
   347
    D3D_FEATURE_LEVEL featureLevels[] = 
dludwig@8410
   348
    {
dludwig@8410
   349
        D3D_FEATURE_LEVEL_11_1,
dludwig@8410
   350
        D3D_FEATURE_LEVEL_11_0,
dludwig@8410
   351
        D3D_FEATURE_LEVEL_10_1,
dludwig@8410
   352
        D3D_FEATURE_LEVEL_10_0,
dludwig@8410
   353
        D3D_FEATURE_LEVEL_9_3,
dludwig@8410
   354
        D3D_FEATURE_LEVEL_9_2,
dludwig@8410
   355
        D3D_FEATURE_LEVEL_9_1
dludwig@8410
   356
    };
dludwig@8410
   357
dludwig@8410
   358
    // Create the Direct3D 11 API device object and a corresponding context.
dludwig@8410
   359
    ComPtr<ID3D11Device> device;
dludwig@8410
   360
    ComPtr<ID3D11DeviceContext> context;
dludwig@8410
   361
    HRESULT result = S_OK;
dludwig@8410
   362
    result = D3D11CreateDevice(
dludwig@8410
   363
        nullptr, // Specify nullptr to use the default adapter.
dludwig@8410
   364
        D3D_DRIVER_TYPE_HARDWARE,
dludwig@8410
   365
        nullptr,
dludwig@8410
   366
        creationFlags, // Set set debug and Direct2D compatibility flags.
dludwig@8410
   367
        featureLevels, // List of feature levels this app can support.
dludwig@8410
   368
        ARRAYSIZE(featureLevels),
dludwig@8410
   369
        D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
dludwig@8410
   370
        &device, // Returns the Direct3D device created.
dludwig@8410
   371
        &data->featureLevel, // Returns feature level of device created.
dludwig@8410
   372
        &context // Returns the device immediate context.
dludwig@8410
   373
        );
dludwig@8410
   374
    if (FAILED(result)) {
dludwig@8410
   375
        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
dludwig@8410
   376
        return result;
dludwig@8410
   377
    }
dludwig@8410
   378
dludwig@8410
   379
    // Get the Direct3D 11.1 API device and context interfaces.
dludwig@8410
   380
    Microsoft::WRL::ComPtr<ID3D11Device1> d3dDevice1;
dludwig@8410
   381
    result = device.As(&(data->d3dDevice));
dludwig@8410
   382
    if (FAILED(result)) {
dludwig@8410
   383
        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
dludwig@8410
   384
        return result;
dludwig@8410
   385
    }
dludwig@8410
   386
dludwig@8410
   387
    result = context.As(&data->d3dContext);
dludwig@8410
   388
    if (FAILED(result)) {
dludwig@8410
   389
        return result;
dludwig@8410
   390
    }
dludwig@8410
   391
dludwig@8410
   392
    // Start loading GPU shaders:
dludwig@8410
   393
    vector<char> fileData;
dludwig@8410
   394
dludwig@8410
   395
    //
dludwig@8410
   396
    // Load in SDL's one and only vertex shader:
dludwig@8410
   397
    //
dludwig@8410
   398
    if (!D3D11_ReadShaderContents(L"SimpleVertexShader.cso", fileData)) {
dludwig@8410
   399
        SDL_SetError("Unable to open SDL's vertex shader file.");
dludwig@8410
   400
        return E_FAIL;
dludwig@8410
   401
    }
dludwig@8410
   402
dludwig@8410
   403
    result = data->d3dDevice->CreateVertexShader(
dludwig@8410
   404
        &fileData[0],
dludwig@8410
   405
        fileData.size(),
dludwig@8410
   406
        nullptr,
dludwig@8410
   407
        &data->vertexShader
dludwig@8410
   408
        );
dludwig@8410
   409
    if (FAILED(result)) {
dludwig@8410
   410
        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
dludwig@8410
   411
        return result;
dludwig@8410
   412
    }
dludwig@8410
   413
dludwig@8410
   414
    //
dludwig@8410
   415
    // Create an input layout for SDL's vertex shader:
dludwig@8410
   416
    //
dludwig@8410
   417
    const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = 
dludwig@8410
   418
    {
dludwig@8410
   419
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
dludwig@8410
   420
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
dludwig@8410
   421
    };
dludwig@8410
   422
dludwig@8410
   423
    result = data->d3dDevice->CreateInputLayout(
dludwig@8410
   424
        vertexDesc,
dludwig@8410
   425
        ARRAYSIZE(vertexDesc),
dludwig@8410
   426
        &fileData[0],
dludwig@8410
   427
        fileData.size(),
dludwig@8410
   428
        &data->inputLayout
dludwig@8410
   429
        );
dludwig@8410
   430
    if (FAILED(result)) {
dludwig@8410
   431
        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
dludwig@8410
   432
        return result;
dludwig@8410
   433
    }
dludwig@8410
   434
dludwig@8410
   435
    //
dludwig@8410
   436
    // Load in SDL's one and only pixel shader (for now, more are likely to follow):
dludwig@8410
   437
    //
dludwig@8410
   438
    if (!D3D11_ReadShaderContents(L"SimplePixelShader.cso", fileData)) {
dludwig@8410
   439
        SDL_SetError("Unable to open SDL's pixel shader file.");
dludwig@8410
   440
        return E_FAIL;
dludwig@8410
   441
    }
dludwig@8410
   442
dludwig@8410
   443
    result = data->d3dDevice->CreatePixelShader(
dludwig@8410
   444
        &fileData[0],
dludwig@8410
   445
        fileData.size(),
dludwig@8410
   446
        nullptr,
dludwig@8410
   447
        &data->pixelShader
dludwig@8410
   448
        );
dludwig@8410
   449
    if (FAILED(result)) {
dludwig@8410
   450
        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
dludwig@8410
   451
        return result;
dludwig@8410
   452
    }
dludwig@8410
   453
dludwig@8410
   454
    //
dludwig@8410
   455
    // Create a vertex buffer:
dludwig@8410
   456
    //
dludwig@8410
   457
    VertexPositionColor vertices[] = 
dludwig@8410
   458
    {
dludwig@8410
   459
        {XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)},
dludwig@8410
   460
        {XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f)},
dludwig@8410
   461
        {XMFLOAT3(1.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f)},
dludwig@8410
   462
        {XMFLOAT3(1.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)},
dludwig@8410
   463
    };
dludwig@8410
   464
dludwig@8410
   465
    data->vertexCount = ARRAYSIZE(vertices);
dludwig@8410
   466
dludwig@8410
   467
    D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
dludwig@8410
   468
    vertexBufferData.pSysMem = vertices;
dludwig@8410
   469
    vertexBufferData.SysMemPitch = 0;
dludwig@8410
   470
    vertexBufferData.SysMemSlicePitch = 0;
dludwig@8410
   471
    CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER);
dludwig@8410
   472
    result = data->d3dDevice->CreateBuffer(
dludwig@8410
   473
        &vertexBufferDesc,
dludwig@8410
   474
        &vertexBufferData,
dludwig@8410
   475
        &data->vertexBuffer
dludwig@8410
   476
        );
dludwig@8410
   477
    if (FAILED(result)) {
dludwig@8410
   478
        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
dludwig@8410
   479
        return result;
dludwig@8410
   480
    }
dludwig@8410
   481
dludwig@8410
   482
    //
dludwig@8410
   483
    // Create a sampler to use when drawing textures:
dludwig@8410
   484
    //
dludwig@8410
   485
    D3D11_SAMPLER_DESC samplerDesc;
dludwig@8410
   486
    samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
dludwig@8410
   487
    samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
dludwig@8410
   488
    samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
dludwig@8410
   489
    samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
dludwig@8410
   490
    samplerDesc.MipLODBias = 0.0f;
dludwig@8410
   491
    samplerDesc.MaxAnisotropy = 1;
dludwig@8410
   492
    samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
dludwig@8410
   493
    samplerDesc.BorderColor[0] = 0.0f;
dludwig@8410
   494
    samplerDesc.BorderColor[1] = 0.0f;
dludwig@8410
   495
    samplerDesc.BorderColor[2] = 0.0f;
dludwig@8410
   496
    samplerDesc.BorderColor[3] = 0.0f;
dludwig@8410
   497
    samplerDesc.MinLOD = 0.0f;
dludwig@8410
   498
    samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
dludwig@8410
   499
    result = data->d3dDevice->CreateSamplerState(
dludwig@8410
   500
        &samplerDesc,
dludwig@8410
   501
        &data->mainSampler
dludwig@8410
   502
        );
dludwig@8410
   503
    if (FAILED(result)) {
dludwig@8410
   504
        WIN_SetErrorFromHRESULT(__FUNCTION__, result);
dludwig@8410
   505
        return result;
dludwig@8410
   506
    }
dludwig@8410
   507
dludwig@8410
   508
    //
dludwig@8410
   509
    // All done!
dludwig@8410
   510
    //
dludwig@8410
   511
    data->loadingComplete = true;       // This variable can probably be factored-out
dludwig@8410
   512
    return S_OK;
dludwig@8410
   513
}
dludwig@8410
   514
dludwig@8400
   515
static int
dludwig@8400
   516
D3D11_UpdateViewport(SDL_Renderer * renderer)
dludwig@8400
   517
{
dludwig@8400
   518
    return 0;
dludwig@8400
   519
}
dludwig@8400
   520
dludwig@8401
   521
static void
dludwig@8401
   522
D3D11_RenderPresent(SDL_Renderer * renderer)
dludwig@8401
   523
{
dludwig@8401
   524
    D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
dludwig@8401
   525
dludwig@8401
   526
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
dludwig@8401
   527
    // The first argument instructs DXGI to block until VSync, putting the application
dludwig@8401
   528
    // to sleep until the next VSync. This ensures we don't waste any cycles rendering
dludwig@8401
   529
    // frames that will never be displayed to the screen.
dludwig@8401
   530
    HRESULT hr = data->swapChain->Present(1, 0);
dludwig@8401
   531
#else
dludwig@8401
   532
    // The application may optionally specify "dirty" or "scroll"
dludwig@8401
   533
    // rects to improve efficiency in certain scenarios.
dludwig@8401
   534
    // This option is not available on Windows Phone 8, to note.
dludwig@8401
   535
    DXGI_PRESENT_PARAMETERS parameters = {0};
dludwig@8401
   536
    parameters.DirtyRectsCount = 0;
dludwig@8401
   537
    parameters.pDirtyRects = nullptr;
dludwig@8401
   538
    parameters.pScrollRect = nullptr;
dludwig@8401
   539
    parameters.pScrollOffset = nullptr;
dludwig@8401
   540
    
dludwig@8401
   541
    // The first argument instructs DXGI to block until VSync, putting the application
dludwig@8401
   542
    // to sleep until the next VSync. This ensures we don't waste any cycles rendering
dludwig@8401
   543
    // frames that will never be displayed to the screen.
dludwig@8401
   544
    HRESULT hr = data->swapChain->Present1(1, 0, &parameters);
dludwig@8401
   545
#endif
dludwig@8401
   546
dludwig@8401
   547
    // Discard the contents of the render target.
dludwig@8401
   548
    // This is a valid operation only when the existing contents will be entirely
dludwig@8401
   549
    // overwritten. If dirty or scroll rects are used, this call should be removed.
dludwig@8401
   550
    data->d3dContext->DiscardView(data->renderTargetView.Get());
dludwig@8401
   551
dludwig@8401
   552
    // If the device was removed either by a disconnect or a driver upgrade, we 
dludwig@8401
   553
    // must recreate all device resources.
dludwig@8401
   554
    if (hr == DXGI_ERROR_DEVICE_REMOVED)
dludwig@8401
   555
    {
dludwig@8401
   556
        extern void WINRT_HandleDeviceLost();   // TODO, WinRT: move lost-device handling into the Direct3D 11.1 renderer, as appropriate
dludwig@8401
   557
        WINRT_HandleDeviceLost();
dludwig@8401
   558
    }
dludwig@8401
   559
    else
dludwig@8401
   560
    {
dludwig@8401
   561
        WIN_SetErrorFromHRESULT(__FUNCTION__, hr);
dludwig@8401
   562
        // 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
   563
    }
dludwig@8401
   564
}
dludwig@8401
   565
dludwig@8400
   566
#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */
dludwig@8400
   567
dludwig@8400
   568
/* vi: set ts=4 sw=4 expandtab: */