SDL_render_d3d11.c 115 KB

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