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