Effect.h 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265
  1. //--------------------------------------------------------------------------------------
  2. // File: Effect.h
  3. //
  4. // Direct3D 11 Effects Header for ID3DX11Effect Implementation
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //
  11. // Copyright (c) Microsoft Corporation. All rights reserved.
  12. //
  13. // http://go.microsoft.com/fwlink/p/?LinkId=271568
  14. //--------------------------------------------------------------------------------------
  15. #pragma once
  16. #include "EffectBinaryFormat.h"
  17. #include "IUnknownImp.h"
  18. #ifdef _DEBUG
  19. extern void __cdecl D3DXDebugPrintf(UINT lvl, _In_z_ _Printf_format_string_ LPCSTR szFormat, ...);
  20. #define DPF D3DXDebugPrintf
  21. #else
  22. #define DPF
  23. #endif
  24. #pragma warning(push)
  25. #pragma warning(disable : 4481)
  26. // VS 2010 considers 'override' to be a extension, but it's part of C++11 as of VS 2012
  27. //////////////////////////////////////////////////////////////////////////
  28. using namespace D3DX11Core;
  29. namespace D3DX11Effects
  30. {
  31. //////////////////////////////////////////////////////////////////////////
  32. // Forward defines
  33. //////////////////////////////////////////////////////////////////////////
  34. struct SBaseBlock;
  35. struct SShaderBlock;
  36. struct SPassBlock;
  37. struct SClassInstance;
  38. struct SInterface;
  39. struct SShaderResource;
  40. struct SUnorderedAccessView;
  41. struct SRenderTargetView;
  42. struct SDepthStencilView;
  43. struct SSamplerBlock;
  44. struct SDepthStencilBlock;
  45. struct SBlendBlock;
  46. struct SRasterizerBlock;
  47. struct SString;
  48. struct SD3DShaderVTable;
  49. struct SClassInstanceGlobalVariable;
  50. struct SAssignment;
  51. struct SVariable;
  52. struct SGlobalVariable;
  53. struct SAnnotation;
  54. struct SConstantBuffer;
  55. class CEffect;
  56. class CEffectLoader;
  57. enum ELhsType;
  58. // Allows the use of 32-bit and 64-bit timers depending on platform type
  59. typedef size_t Timer;
  60. //////////////////////////////////////////////////////////////////////////
  61. // Reflection & Type structures
  62. //////////////////////////////////////////////////////////////////////////
  63. // CEffectMatrix is used internally instead of float arrays
  64. struct CEffectMatrix
  65. {
  66. union
  67. {
  68. struct
  69. {
  70. float _11, _12, _13, _14;
  71. float _21, _22, _23, _24;
  72. float _31, _32, _33, _34;
  73. float _41, _42, _43, _44;
  74. };
  75. float m[4][4];
  76. };
  77. };
  78. struct CEffectVector4
  79. {
  80. float x;
  81. float y;
  82. float z;
  83. float w;
  84. };
  85. union UDataPointer
  86. {
  87. void *pGeneric;
  88. uint8_t *pNumeric;
  89. float *pNumericFloat;
  90. uint32_t *pNumericDword;
  91. int *pNumericInt;
  92. BOOL *pNumericBool;
  93. SString *pString;
  94. SShaderBlock *pShader;
  95. SBaseBlock *pBlock;
  96. SBlendBlock *pBlend;
  97. SDepthStencilBlock *pDepthStencil;
  98. SRasterizerBlock *pRasterizer;
  99. SInterface *pInterface;
  100. SShaderResource *pShaderResource;
  101. SUnorderedAccessView *pUnorderedAccessView;
  102. SRenderTargetView *pRenderTargetView;
  103. SDepthStencilView *pDepthStencilView;
  104. SSamplerBlock *pSampler;
  105. CEffectVector4 *pVector;
  106. CEffectMatrix *pMatrix;
  107. UINT_PTR Offset;
  108. };
  109. enum EMemberDataType
  110. {
  111. MDT_ClassInstance,
  112. MDT_BlendState,
  113. MDT_DepthStencilState,
  114. MDT_RasterizerState,
  115. MDT_SamplerState,
  116. MDT_Buffer,
  117. MDT_ShaderResourceView,
  118. };
  119. struct SMemberDataPointer
  120. {
  121. EMemberDataType Type;
  122. union
  123. {
  124. IUnknown *pGeneric;
  125. ID3D11ClassInstance *pD3DClassInstance;
  126. ID3D11BlendState *pD3DEffectsManagedBlendState;
  127. ID3D11DepthStencilState *pD3DEffectsManagedDepthStencilState;
  128. ID3D11RasterizerState *pD3DEffectsManagedRasterizerState;
  129. ID3D11SamplerState *pD3DEffectsManagedSamplerState;
  130. ID3D11Buffer *pD3DEffectsManagedConstantBuffer;
  131. ID3D11ShaderResourceView*pD3DEffectsManagedTextureBuffer;
  132. } Data;
  133. };
  134. struct SType : public ID3DX11EffectType
  135. {
  136. static const UINT_PTR c_InvalidIndex = (uint32_t) -1;
  137. static const uint32_t c_ScalarSize = sizeof(uint32_t);
  138. // packing rule constants
  139. static const uint32_t c_ScalarsPerRegister = 4;
  140. static const uint32_t c_RegisterSize = c_ScalarsPerRegister * c_ScalarSize; // must be a power of 2!!
  141. EVarType VarType; // numeric, object, struct
  142. uint32_t Elements; // # of array elements (0 for non-arrays)
  143. char *pTypeName; // friendly name of the type: "VS_OUTPUT", "float4", etc.
  144. // *Size and stride values are always 0 for object types
  145. // *Annotations adhere to packing rules (even though they do not reside in constant buffers)
  146. // for consistency's sake
  147. //
  148. // Packing rules:
  149. // *Structures and array elements are always register aligned
  150. // *Single-row values (or, for column major matrices, single-column) are greedily
  151. // packed unless doing so would span a register boundary, in which case they are
  152. // register aligned
  153. uint32_t TotalSize; // Total size of this data type in a constant buffer from
  154. // start to finish (padding in between elements is included,
  155. // but padding at the end is not since that would require
  156. // knowledge of the following data type).
  157. uint32_t Stride; // Number of bytes to advance between elements.
  158. // Typically a multiple of 16 for arrays, vectors, matrices.
  159. // For scalars and small vectors/matrices, this can be 4 or 8.
  160. uint32_t PackedSize; // Size, in bytes, of this data typed when fully packed
  161. union
  162. {
  163. SBinaryNumericType NumericType;
  164. EObjectType ObjectType; // not all values of EObjectType are valid here (e.g. constant buffer)
  165. struct
  166. {
  167. SVariable *pMembers; // array of type instances describing structure members
  168. uint32_t Members;
  169. BOOL ImplementsInterface; // true if this type implements an interface
  170. BOOL HasSuperClass; // true if this type has a parent class
  171. } StructType;
  172. void* InterfaceType; // nothing for interfaces
  173. };
  174. SType() :
  175. VarType(EVT_Invalid),
  176. Elements(0),
  177. pTypeName(nullptr),
  178. TotalSize(0),
  179. Stride(0),
  180. PackedSize(0)
  181. {
  182. C_ASSERT( sizeof(NumericType) <= sizeof(StructType) );
  183. C_ASSERT( sizeof(ObjectType) <= sizeof(StructType) );
  184. C_ASSERT( sizeof(InterfaceType) <= sizeof(StructType) );
  185. ZeroMemory( &StructType, sizeof(StructType) );
  186. }
  187. bool IsEqual(SType *pOtherType) const;
  188. bool IsObjectType(EObjectType ObjType) const
  189. {
  190. return IsObjectTypeHelper(VarType, ObjectType, ObjType);
  191. }
  192. bool IsShader() const
  193. {
  194. return IsShaderHelper(VarType, ObjectType);
  195. }
  196. bool BelongsInConstantBuffer() const
  197. {
  198. return (VarType == EVT_Numeric) || (VarType == EVT_Struct);
  199. }
  200. bool IsStateBlockObject() const
  201. {
  202. return IsStateBlockObjectHelper(VarType, ObjectType);
  203. }
  204. bool IsClassInstance() const
  205. {
  206. return (VarType == EVT_Struct) && StructType.ImplementsInterface;
  207. }
  208. bool IsInterface() const
  209. {
  210. return IsInterfaceHelper(VarType, ObjectType);
  211. }
  212. bool IsShaderResource() const
  213. {
  214. return IsShaderResourceHelper(VarType, ObjectType);
  215. }
  216. bool IsUnorderedAccessView() const
  217. {
  218. return IsUnorderedAccessViewHelper(VarType, ObjectType);
  219. }
  220. bool IsSampler() const
  221. {
  222. return IsSamplerHelper(VarType, ObjectType);
  223. }
  224. bool IsRenderTargetView() const
  225. {
  226. return IsRenderTargetViewHelper(VarType, ObjectType);
  227. }
  228. bool IsDepthStencilView() const
  229. {
  230. return IsDepthStencilViewHelper(VarType, ObjectType);
  231. }
  232. uint32_t GetTotalUnpackedSize(_In_ bool IsSingleElement) const;
  233. uint32_t GetTotalPackedSize(_In_ bool IsSingleElement) const;
  234. HRESULT GetDescHelper(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc, _In_ bool IsSingleElement) const;
  235. STDMETHOD_(bool, IsValid)() override { return true; }
  236. STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override { return GetDescHelper(pDesc, false); }
  237. STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(_In_ uint32_t Index) override;
  238. STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(_In_z_ LPCSTR Name) override;
  239. STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(_In_z_ LPCSTR Semantic) override;
  240. STDMETHOD_(LPCSTR, GetMemberName)(_In_ uint32_t Index) override;
  241. STDMETHOD_(LPCSTR, GetMemberSemantic)(_In_ uint32_t Index) override;
  242. IUNKNOWN_IMP(SType, ID3DX11EffectType, IUnknown);
  243. };
  244. // Represents a type structure for a single element.
  245. // It seems pretty trivial, but it has a different virtual table which enables
  246. // us to accurately represent a type that consists of a single element
  247. struct SSingleElementType : public ID3DX11EffectType
  248. {
  249. SType *pType;
  250. STDMETHOD_(bool, IsValid)() override { return true; }
  251. STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override { return ((SType*)pType)->GetDescHelper(pDesc, true); }
  252. STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(uint32_t Index) override { return ((SType*)pType)->GetMemberTypeByIndex(Index); }
  253. STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(LPCSTR Name) override { return ((SType*)pType)->GetMemberTypeByName(Name); }
  254. STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(LPCSTR Semantic) override { return ((SType*)pType)->GetMemberTypeBySemantic(Semantic); }
  255. STDMETHOD_(LPCSTR, GetMemberName)(uint32_t Index) override { return ((SType*)pType)->GetMemberName(Index); }
  256. STDMETHOD_(LPCSTR, GetMemberSemantic)(uint32_t Index) override { return ((SType*)pType)->GetMemberSemantic(Index); }
  257. IUNKNOWN_IMP(SSingleElementType, ID3DX11EffectType, IUnknown);
  258. };
  259. //////////////////////////////////////////////////////////////////////////
  260. // Block definitions
  261. //////////////////////////////////////////////////////////////////////////
  262. void * GetBlockByIndex(EVarType VarType, EObjectType ObjectType, void *pBaseBlock, uint32_t Index);
  263. struct SBaseBlock
  264. {
  265. EBlockType BlockType;
  266. bool IsUserManaged:1;
  267. uint32_t AssignmentCount;
  268. SAssignment *pAssignments;
  269. SBaseBlock();
  270. bool ApplyAssignments(CEffect *pEffect);
  271. inline SSamplerBlock *AsSampler() const
  272. {
  273. assert( BlockType == EBT_Sampler );
  274. return (SSamplerBlock*) this;
  275. }
  276. inline SDepthStencilBlock *AsDepthStencil() const
  277. {
  278. assert( BlockType == EBT_DepthStencil );
  279. return (SDepthStencilBlock*) this;
  280. }
  281. inline SBlendBlock *AsBlend() const
  282. {
  283. assert( BlockType == EBT_Blend );
  284. return (SBlendBlock*) this;
  285. }
  286. inline SRasterizerBlock *AsRasterizer() const
  287. {
  288. assert( BlockType == EBT_Rasterizer );
  289. return (SRasterizerBlock*) this;
  290. }
  291. inline SPassBlock *AsPass() const
  292. {
  293. assert( BlockType == EBT_Pass );
  294. return (SPassBlock*) this;
  295. }
  296. };
  297. struct STechnique : public ID3DX11EffectTechnique
  298. {
  299. char *pName;
  300. uint32_t PassCount;
  301. SPassBlock *pPasses;
  302. uint32_t AnnotationCount;
  303. SAnnotation *pAnnotations;
  304. bool InitiallyValid;
  305. bool HasDependencies;
  306. STechnique();
  307. STDMETHOD_(bool, IsValid)() override;
  308. STDMETHOD(GetDesc)(_Out_ D3DX11_TECHNIQUE_DESC *pDesc) override;
  309. STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
  310. STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
  311. STDMETHOD_(ID3DX11EffectPass*, GetPassByIndex)(_In_ uint32_t Index) override;
  312. STDMETHOD_(ID3DX11EffectPass*, GetPassByName)(_In_z_ LPCSTR Name) override;
  313. STDMETHOD(ComputeStateBlockMask)(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask) override;
  314. IUNKNOWN_IMP(STechnique, ID3DX11EffectTechnique, IUnknown);
  315. };
  316. struct SGroup : public ID3DX11EffectGroup
  317. {
  318. char *pName;
  319. uint32_t TechniqueCount;
  320. STechnique *pTechniques;
  321. uint32_t AnnotationCount;
  322. SAnnotation *pAnnotations;
  323. bool InitiallyValid;
  324. bool HasDependencies;
  325. SGroup();
  326. STDMETHOD_(bool, IsValid)() override;
  327. STDMETHOD(GetDesc)(_Out_ D3DX11_GROUP_DESC *pDesc) override;
  328. STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
  329. STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
  330. STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByIndex)(_In_ uint32_t Index) override;
  331. STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByName)(_In_z_ LPCSTR Name) override;
  332. IUNKNOWN_IMP(SGroup, ID3DX11EffectGroup, IUnknown);
  333. };
  334. struct SPassBlock : SBaseBlock, public ID3DX11EffectPass
  335. {
  336. struct
  337. {
  338. ID3D11BlendState* pBlendState;
  339. FLOAT BlendFactor[4];
  340. uint32_t SampleMask;
  341. ID3D11DepthStencilState *pDepthStencilState;
  342. uint32_t StencilRef;
  343. union
  344. {
  345. D3D11_SO_DECLARATION_ENTRY *pEntry;
  346. char *pEntryDesc;
  347. } GSSODesc;
  348. // Pass assignments can write directly into these
  349. SBlendBlock *pBlendBlock;
  350. SDepthStencilBlock *pDepthStencilBlock;
  351. SRasterizerBlock *pRasterizerBlock;
  352. uint32_t RenderTargetViewCount;
  353. SRenderTargetView *pRenderTargetViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
  354. SDepthStencilView *pDepthStencilView;
  355. SShaderBlock *pVertexShaderBlock;
  356. SShaderBlock *pPixelShaderBlock;
  357. SShaderBlock *pGeometryShaderBlock;
  358. SShaderBlock *pComputeShaderBlock;
  359. SShaderBlock *pDomainShaderBlock;
  360. SShaderBlock *pHullShaderBlock;
  361. } BackingStore;
  362. char *pName;
  363. uint32_t AnnotationCount;
  364. SAnnotation *pAnnotations;
  365. CEffect *pEffect;
  366. bool InitiallyValid; // validity of all state objects and shaders in pass upon BindToDevice
  367. bool HasDependencies; // if pass expressions or pass state blocks have dependencies on variables (if true, IsValid != InitiallyValid possibly)
  368. SPassBlock();
  369. void ApplyPassAssignments();
  370. bool CheckShaderDependencies( _In_ const SShaderBlock* pBlock );
  371. bool CheckDependencies();
  372. template<EObjectType EShaderType>
  373. HRESULT GetShaderDescHelper(_Out_ D3DX11_PASS_SHADER_DESC *pDesc);
  374. STDMETHOD_(bool, IsValid)() override;
  375. STDMETHOD(GetDesc)(_Out_ D3DX11_PASS_DESC *pDesc) override;
  376. STDMETHOD(GetVertexShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
  377. STDMETHOD(GetGeometryShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
  378. STDMETHOD(GetPixelShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
  379. STDMETHOD(GetHullShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
  380. STDMETHOD(GetDomainShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
  381. STDMETHOD(GetComputeShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
  382. STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
  383. STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
  384. STDMETHOD(Apply)(_In_ uint32_t Flags, _In_ ID3D11DeviceContext* pContext) override;
  385. STDMETHOD(ComputeStateBlockMask)(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask) override;
  386. IUNKNOWN_IMP(SPassBlock, ID3DX11EffectPass, IUnknown);
  387. };
  388. struct SDepthStencilBlock : SBaseBlock
  389. {
  390. ID3D11DepthStencilState *pDSObject;
  391. D3D11_DEPTH_STENCIL_DESC BackingStore;
  392. bool IsValid;
  393. SDepthStencilBlock();
  394. };
  395. struct SBlendBlock : SBaseBlock
  396. {
  397. ID3D11BlendState *pBlendObject;
  398. D3D11_BLEND_DESC BackingStore;
  399. bool IsValid;
  400. SBlendBlock();
  401. };
  402. struct SRasterizerBlock : SBaseBlock
  403. {
  404. ID3D11RasterizerState *pRasterizerObject;
  405. D3D11_RASTERIZER_DESC BackingStore;
  406. bool IsValid;
  407. SRasterizerBlock();
  408. };
  409. struct SSamplerBlock : SBaseBlock
  410. {
  411. ID3D11SamplerState *pD3DObject;
  412. struct
  413. {
  414. D3D11_SAMPLER_DESC SamplerDesc;
  415. // Sampler "TEXTURE" assignments can write directly into this
  416. SShaderResource *pTexture;
  417. } BackingStore;
  418. SSamplerBlock();
  419. };
  420. struct SInterface
  421. {
  422. SClassInstanceGlobalVariable* pClassInstance;
  423. SInterface()
  424. {
  425. pClassInstance = nullptr;
  426. }
  427. };
  428. struct SShaderResource
  429. {
  430. ID3D11ShaderResourceView *pShaderResource;
  431. SShaderResource()
  432. {
  433. pShaderResource = nullptr;
  434. }
  435. };
  436. struct SUnorderedAccessView
  437. {
  438. ID3D11UnorderedAccessView *pUnorderedAccessView;
  439. SUnorderedAccessView()
  440. {
  441. pUnorderedAccessView = nullptr;
  442. }
  443. };
  444. struct SRenderTargetView
  445. {
  446. ID3D11RenderTargetView *pRenderTargetView;
  447. SRenderTargetView();
  448. };
  449. struct SDepthStencilView
  450. {
  451. ID3D11DepthStencilView *pDepthStencilView;
  452. SDepthStencilView();
  453. };
  454. template<class T, class D3DTYPE> struct SShaderDependency
  455. {
  456. uint32_t StartIndex;
  457. uint32_t Count;
  458. T *ppFXPointers; // Array of ptrs to FX objects (CBs, SShaderResources, etc)
  459. D3DTYPE *ppD3DObjects; // Array of ptrs to matching D3D objects
  460. SShaderDependency()
  461. {
  462. StartIndex = Count = 0;
  463. ppD3DObjects = nullptr;
  464. ppFXPointers = nullptr;
  465. }
  466. };
  467. typedef SShaderDependency<SConstantBuffer*, ID3D11Buffer*> SShaderCBDependency;
  468. typedef SShaderDependency<SSamplerBlock*, ID3D11SamplerState*> SShaderSamplerDependency;
  469. typedef SShaderDependency<SShaderResource*, ID3D11ShaderResourceView*> SShaderResourceDependency;
  470. typedef SShaderDependency<SUnorderedAccessView*, ID3D11UnorderedAccessView*> SUnorderedAccessViewDependency;
  471. typedef SShaderDependency<SInterface*, ID3D11ClassInstance*> SInterfaceDependency;
  472. // Shader VTables are used to eliminate branching in ApplyShaderBlock.
  473. // The effect owns one D3DShaderVTables for each shader stage
  474. struct SD3DShaderVTable
  475. {
  476. void ( __stdcall ID3D11DeviceContext::*pSetShader)(ID3D11DeviceChild* pShader, ID3D11ClassInstance*const* ppClassInstances, uint32_t NumClassInstances);
  477. void ( __stdcall ID3D11DeviceContext::*pSetConstantBuffers)(uint32_t StartConstantSlot, uint32_t NumBuffers, ID3D11Buffer *const *pBuffers);
  478. void ( __stdcall ID3D11DeviceContext::*pSetSamplers)(uint32_t Offset, uint32_t NumSamplers, ID3D11SamplerState*const* pSamplers);
  479. void ( __stdcall ID3D11DeviceContext::*pSetShaderResources)(uint32_t Offset, uint32_t NumResources, ID3D11ShaderResourceView *const *pResources);
  480. HRESULT ( __stdcall ID3D11Device::*pCreateShader)(const void *pShaderBlob, size_t ShaderBlobSize, ID3D11ClassLinkage* pClassLinkage, ID3D11DeviceChild **ppShader);
  481. };
  482. struct SShaderBlock
  483. {
  484. enum ESigType
  485. {
  486. ST_Input,
  487. ST_Output,
  488. ST_PatchConstant,
  489. };
  490. struct SInterfaceParameter
  491. {
  492. char *pName;
  493. uint32_t Index;
  494. };
  495. // this data is classified as reflection-only and will all be discarded at runtime
  496. struct SReflectionData
  497. {
  498. uint8_t *pBytecode;
  499. uint32_t BytecodeLength;
  500. char *pStreamOutDecls[4]; // set with ConstructGSWithSO
  501. uint32_t RasterizedStream; // set with ConstructGSWithSO
  502. BOOL IsNullGS;
  503. ID3D11ShaderReflection *pReflection;
  504. uint32_t InterfaceParameterCount; // set with BindInterfaces (used for function interface parameters)
  505. SInterfaceParameter *pInterfaceParameters; // set with BindInterfaces (used for function interface parameters)
  506. };
  507. bool IsValid;
  508. SD3DShaderVTable *pVT;
  509. // This value is nullptr if the shader is nullptr or was never initialized
  510. SReflectionData *pReflectionData;
  511. ID3D11DeviceChild *pD3DObject;
  512. uint32_t CBDepCount;
  513. SShaderCBDependency *pCBDeps;
  514. uint32_t SampDepCount;
  515. SShaderSamplerDependency *pSampDeps;
  516. uint32_t InterfaceDepCount;
  517. SInterfaceDependency *pInterfaceDeps;
  518. uint32_t ResourceDepCount;
  519. SShaderResourceDependency *pResourceDeps;
  520. uint32_t UAVDepCount;
  521. SUnorderedAccessViewDependency *pUAVDeps;
  522. uint32_t TBufferDepCount;
  523. SConstantBuffer **ppTbufDeps;
  524. ID3DBlob *pInputSignatureBlob; // The input signature is separated from the bytecode because it
  525. // is always available, even after Optimize() has been called.
  526. SShaderBlock(SD3DShaderVTable *pVirtualTable = nullptr);
  527. EObjectType GetShaderType();
  528. HRESULT OnDeviceBind();
  529. // Public API helpers
  530. HRESULT ComputeStateBlockMask(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask);
  531. HRESULT GetShaderDesc(_Out_ D3DX11_EFFECT_SHADER_DESC *pDesc, _In_ bool IsInline);
  532. HRESULT GetVertexShader(_Outptr_ ID3D11VertexShader **ppVS);
  533. HRESULT GetGeometryShader(_Outptr_ ID3D11GeometryShader **ppGS);
  534. HRESULT GetPixelShader(_Outptr_ ID3D11PixelShader **ppPS);
  535. HRESULT GetHullShader(_Outptr_ ID3D11HullShader **ppHS);
  536. HRESULT GetDomainShader(_Outptr_ ID3D11DomainShader **ppDS);
  537. HRESULT GetComputeShader(_Outptr_ ID3D11ComputeShader **ppCS);
  538. HRESULT GetSignatureElementDesc(_In_ ESigType SigType, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc);
  539. };
  540. struct SString
  541. {
  542. char *pString;
  543. SString();
  544. };
  545. //////////////////////////////////////////////////////////////////////////
  546. // Global Variable & Annotation structure/interface definitions
  547. //////////////////////////////////////////////////////////////////////////
  548. //
  549. // This is a general structure that can describe
  550. // annotations, variables, and structure members
  551. //
  552. struct SVariable
  553. {
  554. // For annotations/variables/variable members:
  555. // 1) If numeric, pointer to data (for variables: points into backing store,
  556. // for annotations, points into reflection heap)
  557. // OR
  558. // 2) If object, pointer to the block. If object array, subsequent array elements are found in
  559. // contiguous blocks; the Nth block is found by ((<SpecificBlockType> *) pBlock) + N
  560. // (this is because variables that are arrays of objects have their blocks allocated contiguously)
  561. //
  562. // For structure members:
  563. // Offset of this member (in bytes) from parent structure (structure members must be numeric/struct)
  564. UDataPointer Data;
  565. union
  566. {
  567. uint32_t MemberDataOffsetPlus4; // 4 added so that 0 == nullptr can represent "unused"
  568. SMemberDataPointer *pMemberData;
  569. };
  570. SType *pType;
  571. char *pName;
  572. char *pSemantic;
  573. uint32_t ExplicitBindPoint;
  574. SVariable()
  575. {
  576. ZeroMemory(this, sizeof(*this));
  577. ExplicitBindPoint = uint32_t(-1);
  578. }
  579. };
  580. // Template definitions for all of the various ID3DX11EffectVariable specializations
  581. #include "EffectVariable.inl"
  582. ////////////////////////////////////////////////////////////////////////////////
  583. // ID3DX11EffectShaderVariable (SAnonymousShader implementation)
  584. ////////////////////////////////////////////////////////////////////////////////
  585. struct SAnonymousShader : public TUncastableVariable<ID3DX11EffectShaderVariable>, public ID3DX11EffectType
  586. {
  587. SShaderBlock *pShaderBlock;
  588. SAnonymousShader(_In_opt_ SShaderBlock *pBlock = nullptr);
  589. // ID3DX11EffectShaderVariable interface
  590. STDMETHOD_(bool, IsValid)() override;
  591. STDMETHOD_(ID3DX11EffectType*, GetType)() override;
  592. STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) override;
  593. STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
  594. STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
  595. STDMETHOD_(ID3DX11EffectVariable*, GetMemberByIndex)(_In_ uint32_t Index) override;
  596. STDMETHOD_(ID3DX11EffectVariable*, GetMemberByName)(_In_z_ LPCSTR Name) override;
  597. STDMETHOD_(ID3DX11EffectVariable*, GetMemberBySemantic)(_In_z_ LPCSTR Semantic) override;
  598. STDMETHOD_(ID3DX11EffectVariable*, GetElement)(_In_ uint32_t Index) override;
  599. STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)() override;
  600. // other casts are handled by TUncastableVariable
  601. STDMETHOD_(ID3DX11EffectShaderVariable*, AsShader)() override;
  602. STDMETHOD(SetRawValue)(_In_reads_bytes_(Count) const void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
  603. STDMETHOD(GetRawValue)(_Out_writes_bytes_(Count) void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
  604. STDMETHOD(GetShaderDesc)(_In_ uint32_t ShaderIndex, _Out_ D3DX11_EFFECT_SHADER_DESC *pDesc) override;
  605. STDMETHOD(GetVertexShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11VertexShader **ppVS) override;
  606. STDMETHOD(GetGeometryShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11GeometryShader **ppGS) override;
  607. STDMETHOD(GetPixelShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11PixelShader **ppPS) override;
  608. STDMETHOD(GetHullShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11HullShader **ppHS) override;
  609. STDMETHOD(GetDomainShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11DomainShader **ppDS) override;
  610. STDMETHOD(GetComputeShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11ComputeShader **ppCS) override;
  611. STDMETHOD(GetInputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override;
  612. STDMETHOD(GetOutputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override;
  613. STDMETHOD(GetPatchConstantSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override;
  614. // ID3DX11EffectType interface
  615. STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override;
  616. STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(_In_ uint32_t Index) override;
  617. STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(_In_z_ LPCSTR Name) override;
  618. STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(_In_z_ LPCSTR Semantic) override;
  619. STDMETHOD_(LPCSTR, GetMemberName)(_In_ uint32_t Index) override;
  620. STDMETHOD_(LPCSTR, GetMemberSemantic)(_In_ uint32_t Index) override;
  621. IUNKNOWN_IMP(SAnonymousShader, ID3DX11EffectShaderVariable, ID3DX11EffectVariable);
  622. };
  623. ////////////////////////////////////////////////////////////////////////////////
  624. // ID3DX11EffectConstantBuffer (SConstantBuffer implementation)
  625. ////////////////////////////////////////////////////////////////////////////////
  626. struct SConstantBuffer : public TUncastableVariable<ID3DX11EffectConstantBuffer>, public ID3DX11EffectType
  627. {
  628. ID3D11Buffer *pD3DObject;
  629. SShaderResource TBuffer; // nullptr iff IsTbuffer == false
  630. uint8_t *pBackingStore;
  631. uint32_t Size; // in bytes
  632. char *pName;
  633. uint32_t AnnotationCount;
  634. SAnnotation *pAnnotations;
  635. uint32_t VariableCount; // # of variables contained in this cbuffer
  636. SGlobalVariable *pVariables; // array of size [VariableCount], points into effect's contiguous variable list
  637. uint32_t ExplicitBindPoint; // Used when a CB has been explicitly bound (register(bXX)). -1 if not
  638. bool IsDirty:1; // Set when any member is updated; cleared on CB apply
  639. bool IsTBuffer:1; // true iff TBuffer.pShaderResource != nullptr
  640. bool IsUserManaged:1; // Set if you don't want effects to update this buffer
  641. bool IsEffectOptimized:1;// Set if the effect has been optimized
  642. bool IsUsedByExpression:1;// Set if used by any expressions
  643. bool IsUserPacked:1; // Set if the elements have user-specified offsets
  644. bool IsSingle:1; // Set to true if you want to share this CB with cloned Effects
  645. bool IsNonUpdatable:1; // Set to true if you want to share this CB with cloned Effects
  646. union
  647. {
  648. // These are used to store the original ID3D11Buffer* for use in UndoSetConstantBuffer
  649. uint32_t MemberDataOffsetPlus4; // 4 added so that 0 == nullptr can represent "unused"
  650. SMemberDataPointer *pMemberData;
  651. };
  652. CEffect *pEffect;
  653. SConstantBuffer()
  654. {
  655. pD3DObject = nullptr;
  656. ZeroMemory(&TBuffer, sizeof(TBuffer));
  657. ExplicitBindPoint = uint32_t(-1);
  658. pBackingStore = nullptr;
  659. Size = 0;
  660. pName = nullptr;
  661. VariableCount = 0;
  662. pVariables = nullptr;
  663. AnnotationCount = 0;
  664. pAnnotations = nullptr;
  665. IsDirty = false;
  666. IsTBuffer = false;
  667. IsUserManaged = false;
  668. IsEffectOptimized = false;
  669. IsUsedByExpression = false;
  670. IsUserPacked = false;
  671. IsSingle = false;
  672. IsNonUpdatable = false;
  673. pEffect = nullptr;
  674. }
  675. bool ClonedSingle() const;
  676. // ID3DX11EffectConstantBuffer interface
  677. STDMETHOD_(bool, IsValid)() override;
  678. STDMETHOD_(ID3DX11EffectType*, GetType)() override;
  679. STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) override;
  680. STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
  681. STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
  682. STDMETHOD_(ID3DX11EffectVariable*, GetMemberByIndex)(_In_ uint32_t Index) override;
  683. STDMETHOD_(ID3DX11EffectVariable*, GetMemberByName)(_In_z_ LPCSTR Name) override;
  684. STDMETHOD_(ID3DX11EffectVariable*, GetMemberBySemantic)(_In_z_ LPCSTR Semantic) override;
  685. STDMETHOD_(ID3DX11EffectVariable*, GetElement)(_In_ uint32_t Index) override;
  686. STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)() override;
  687. // other casts are handled by TUncastableVariable
  688. STDMETHOD_(ID3DX11EffectConstantBuffer*, AsConstantBuffer)() override;
  689. STDMETHOD(SetRawValue)(_In_reads_bytes_(Count) const void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
  690. STDMETHOD(GetRawValue)(_Out_writes_bytes_(Count) void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
  691. STDMETHOD(SetConstantBuffer)(_In_ ID3D11Buffer *pConstantBuffer) override;
  692. STDMETHOD(GetConstantBuffer)(_Outptr_ ID3D11Buffer **ppConstantBuffer) override;
  693. STDMETHOD(UndoSetConstantBuffer)() override;
  694. STDMETHOD(SetTextureBuffer)(_In_ ID3D11ShaderResourceView *pTextureBuffer) override;
  695. STDMETHOD(GetTextureBuffer)(_Outptr_ ID3D11ShaderResourceView **ppTextureBuffer) override;
  696. STDMETHOD(UndoSetTextureBuffer)() override;
  697. // ID3DX11EffectType interface
  698. STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override;
  699. STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(_In_ uint32_t Index) override;
  700. STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(_In_z_ LPCSTR Name) override;
  701. STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(_In_z_ LPCSTR Semantic) override;
  702. STDMETHOD_(LPCSTR, GetMemberName)(_In_ uint32_t Index) override;
  703. STDMETHOD_(LPCSTR, GetMemberSemantic)(_In_ uint32_t Index) override;
  704. IUNKNOWN_IMP(SConstantBuffer, ID3DX11EffectConstantBuffer, ID3DX11EffectVariable);
  705. };
  706. //////////////////////////////////////////////////////////////////////////
  707. // Assignments
  708. //////////////////////////////////////////////////////////////////////////
  709. enum ERuntimeAssignmentType
  710. {
  711. ERAT_Invalid,
  712. // [Destination] refers to the destination location, which is always the backing store of the pass/state block.
  713. // [Source] refers to the current source of data, always coming from either a constant buffer's
  714. // backing store (for numeric assignments), an object variable's block array, or an anonymous (unowned) block
  715. // Numeric variables:
  716. ERAT_Constant, // Source is unused.
  717. // No dependencies; this assignment can be safely removed after load.
  718. ERAT_NumericVariable, // Source points to the CB's backing store where the value lives.
  719. // 1 dependency: the variable itself.
  720. ERAT_NumericConstIndex, // Source points to the CB's backing store where the value lives, offset by N.
  721. // 1 dependency: the variable array being indexed.
  722. ERAT_NumericVariableIndex, // Source points to the last used element of the variable in the CB's backing store.
  723. // 2 dependencies: the index variable followed by the array variable.
  724. // Object variables:
  725. ERAT_ObjectInlineShader, // An anonymous, immutable shader block pointer is copied to the destination immediately.
  726. // No dependencies; this assignment can be safely removed after load.
  727. ERAT_ObjectVariable, // A pointer to the block owned by the object variable is copied to the destination immediately.
  728. // No dependencies; this assignment can be safely removed after load.
  729. ERAT_ObjectConstIndex, // A pointer to the Nth block owned by an object variable is copied to the destination immediately.
  730. // No dependencies; this assignment can be safely removed after load.
  731. ERAT_ObjectVariableIndex, // Source points to the first block owned by an object variable array
  732. // (the offset from this, N, is taken from another variable).
  733. // 1 dependency: the variable being used to index the array.
  734. };
  735. struct SAssignment
  736. {
  737. struct SDependency
  738. {
  739. SGlobalVariable *pVariable;
  740. SDependency()
  741. {
  742. pVariable = nullptr;
  743. }
  744. };
  745. ELhsType LhsType; // PS, VS, DepthStencil etc.
  746. // The value of SAssignment.AssignmentType determines how the other fields behave
  747. // (DependencyCount, pDependencies, Destination, and Source)
  748. ERuntimeAssignmentType AssignmentType;
  749. Timer LastRecomputedTime;
  750. // see comments in ERuntimeAssignmentType for how dependencies and data pointers are handled
  751. uint32_t DependencyCount;
  752. SDependency *pDependencies;
  753. UDataPointer Destination; // This value never changes after load, and always refers to the backing store
  754. UDataPointer Source; // This value, on the other hand, can change if variable- or expression- driven
  755. uint32_t DataSize : 16; // Size of the data element to be copied in bytes (if numeric) or
  756. // stride of the block type (if object)
  757. uint32_t MaxElements : 16; // Max allowable index (needed because we don't store object arrays as dependencies,
  758. // and therefore have no way of getting their Element count)
  759. bool IsObjectAssignment() // True for Shader and RObject assignments (the type that appear in pass blocks)
  760. {
  761. return IsObjectAssignmentHelper(LhsType);
  762. }
  763. SAssignment()
  764. {
  765. LhsType = ELHS_Invalid;
  766. AssignmentType = ERAT_Invalid;
  767. Destination.pGeneric = nullptr;
  768. Source.pGeneric = nullptr;
  769. LastRecomputedTime = 0;
  770. DependencyCount = 0;
  771. pDependencies = nullptr;
  772. DataSize = 0;
  773. }
  774. };
  775. //////////////////////////////////////////////////////////////////////////
  776. // Private effect heaps
  777. //////////////////////////////////////////////////////////////////////////
  778. // Used to efficiently reallocate data
  779. // 1) For every piece of data that needs reallocation, move it to its new location
  780. // and add an entry into the table
  781. // 2) For everyone that references one of these data blocks, do a quick table lookup
  782. // to find the old pointer and then replace it with the new one
  783. struct SPointerMapping
  784. {
  785. void *pOld;
  786. void *pNew;
  787. static bool AreMappingsEqual(const SPointerMapping &pMap1, const SPointerMapping &pMap2)
  788. {
  789. return (pMap1.pOld == pMap2.pOld);
  790. }
  791. uint32_t Hash()
  792. {
  793. // hash the pointer itself
  794. // (using the pointer as a hash would be very bad)
  795. return ComputeHash((uint8_t*)&pOld, sizeof(pOld));
  796. }
  797. };
  798. typedef CEffectHashTableWithPrivateHeap<SPointerMapping, SPointerMapping::AreMappingsEqual> CPointerMappingTable;
  799. // Assist adding data to a block of memory
  800. class CEffectHeap
  801. {
  802. protected:
  803. uint8_t *m_pData;
  804. uint32_t m_dwBufferSize;
  805. uint32_t m_dwSize;
  806. template <bool bCopyData>
  807. HRESULT AddDataInternal(_In_reads_bytes_(dwSize) const void *pData, _In_ uint32_t dwSize, _Outptr_ void **ppPointer);
  808. public:
  809. HRESULT ReserveMemory(uint32_t dwSize);
  810. uint32_t GetSize();
  811. uint8_t* GetDataStart() { return m_pData; }
  812. // AddData and AddString append existing data to the buffer - they change m_dwSize. Users are
  813. // not expected to modify the data pointed to by the return pointer
  814. HRESULT AddString(_In_z_ const char *pString, _Outptr_result_z_ char **ppPointer);
  815. HRESULT AddData(_In_reads_(dwSize) const void *pData, _In_ uint32_t dwSize, _Outptr_ void **ppPointer);
  816. // Allocate behaves like a standard new - it will allocate memory, move m_dwSize. The caller is
  817. // expected to use the returned pointer
  818. void* Allocate(uint32_t dwSize);
  819. // Move data from the general heap and optional free memory
  820. HRESULT MoveData(_Inout_updates_bytes_(size) void **ppData, _In_ uint32_t size);
  821. HRESULT MoveString(_Inout_updates_z_(1) char **ppStringData);
  822. HRESULT MoveInterfaceParameters(_In_ uint32_t InterfaceCount, _Inout_updates_(1) SShaderBlock::SInterfaceParameter **ppInterfaces);
  823. HRESULT MoveEmptyDataBlock(_Inout_updates_(1) void **ppData, _In_ uint32_t size);
  824. bool IsInHeap(_In_ void *pData) const
  825. {
  826. return (pData >= m_pData && pData < (m_pData + m_dwBufferSize));
  827. }
  828. CEffectHeap();
  829. ~CEffectHeap();
  830. };
  831. class CEffectReflection
  832. {
  833. public:
  834. // Single memory block support
  835. CEffectHeap m_Heap;
  836. };
  837. class CEffect : public ID3DX11Effect
  838. {
  839. friend struct SBaseBlock;
  840. friend struct SPassBlock;
  841. friend class CEffectLoader;
  842. friend struct SConstantBuffer;
  843. friend struct TSamplerVariable<TGlobalVariable<ID3DX11EffectSamplerVariable>>;
  844. friend struct TSamplerVariable<TVariable<TMember<ID3DX11EffectSamplerVariable>>>;
  845. protected:
  846. uint32_t m_RefCount;
  847. uint32_t m_Flags;
  848. // Private heap - all pointers should point into here
  849. CEffectHeap m_Heap;
  850. // Reflection object
  851. CEffectReflection *m_pReflection;
  852. // global variables in the effect (aka parameters)
  853. uint32_t m_VariableCount;
  854. SGlobalVariable *m_pVariables;
  855. // anonymous shader variables (one for every inline shader assignment)
  856. uint32_t m_AnonymousShaderCount;
  857. SAnonymousShader *m_pAnonymousShaders;
  858. // techniques within this effect (the actual data is located in each group)
  859. uint32_t m_TechniqueCount;
  860. // groups within this effect
  861. uint32_t m_GroupCount;
  862. SGroup *m_pGroups;
  863. SGroup *m_pNullGroup;
  864. uint32_t m_ShaderBlockCount;
  865. SShaderBlock *m_pShaderBlocks;
  866. uint32_t m_DepthStencilBlockCount;
  867. SDepthStencilBlock *m_pDepthStencilBlocks;
  868. uint32_t m_BlendBlockCount;
  869. SBlendBlock *m_pBlendBlocks;
  870. uint32_t m_RasterizerBlockCount;
  871. SRasterizerBlock *m_pRasterizerBlocks;
  872. uint32_t m_SamplerBlockCount;
  873. SSamplerBlock *m_pSamplerBlocks;
  874. uint32_t m_MemberDataCount;
  875. SMemberDataPointer *m_pMemberDataBlocks;
  876. uint32_t m_InterfaceCount;
  877. SInterface *m_pInterfaces;
  878. uint32_t m_CBCount;
  879. SConstantBuffer *m_pCBs;
  880. uint32_t m_StringCount;
  881. SString *m_pStrings;
  882. uint32_t m_ShaderResourceCount;
  883. SShaderResource *m_pShaderResources;
  884. uint32_t m_UnorderedAccessViewCount;
  885. SUnorderedAccessView *m_pUnorderedAccessViews;
  886. uint32_t m_RenderTargetViewCount;
  887. SRenderTargetView *m_pRenderTargetViews;
  888. uint32_t m_DepthStencilViewCount;
  889. SDepthStencilView *m_pDepthStencilViews;
  890. Timer m_LocalTimer;
  891. // temporary index variable for assignment evaluation
  892. uint32_t m_FXLIndex;
  893. ID3D11Device *m_pDevice;
  894. ID3D11DeviceContext *m_pContext;
  895. ID3D11ClassLinkage *m_pClassLinkage;
  896. // Master lists of reflection interfaces
  897. CEffectVectorOwner<SSingleElementType> m_pTypeInterfaces;
  898. CEffectVectorOwner<SMember> m_pMemberInterfaces;
  899. //////////////////////////////////////////////////////////////////////////
  900. // String & Type pooling
  901. typedef SType *LPSRUNTIMETYPE;
  902. static bool AreTypesEqual(const LPSRUNTIMETYPE &pType1, const LPSRUNTIMETYPE &pType2) { return (pType1->IsEqual(pType2)); }
  903. static bool AreStringsEqual(const LPCSTR &pStr1, const LPCSTR &pStr2) { return strcmp(pStr1, pStr2) == 0; }
  904. typedef CEffectHashTableWithPrivateHeap<SType *, AreTypesEqual> CTypeHashTable;
  905. typedef CEffectHashTableWithPrivateHeap<LPCSTR, AreStringsEqual> CStringHashTable;
  906. // These are used to pool types & type-related strings
  907. // until Optimize() is called
  908. CTypeHashTable *m_pTypePool;
  909. CStringHashTable *m_pStringPool;
  910. CDataBlockStore *m_pPooledHeap;
  911. // After Optimize() is called, the type/string pools should be deleted and all
  912. // remaining data should be migrated into the optimized type heap
  913. CEffectHeap *m_pOptimizedTypeHeap;
  914. // Pools a string or type and modifies the pointer
  915. void AddStringToPool(const char **ppString);
  916. void AddTypeToPool(SType **ppType);
  917. HRESULT OptimizeTypes(_Inout_ CPointerMappingTable *pMappingTable, _In_ bool Cloning = false);
  918. //////////////////////////////////////////////////////////////////////////
  919. // Runtime (performance critical)
  920. void ApplyShaderBlock(_In_ SShaderBlock *pBlock);
  921. bool ApplyRenderStateBlock(_In_ SBaseBlock *pBlock);
  922. bool ApplySamplerBlock(_In_ SSamplerBlock *pBlock);
  923. void ApplyPassBlock(_Inout_ SPassBlock *pBlock);
  924. bool EvaluateAssignment(_Inout_ SAssignment *pAssignment);
  925. bool ValidateShaderBlock(_Inout_ SShaderBlock* pBlock );
  926. bool ValidatePassBlock(_Inout_ SPassBlock* pBlock );
  927. //////////////////////////////////////////////////////////////////////////
  928. // Non-runtime functions (not performance critical)
  929. SGlobalVariable *FindLocalVariableByName(_In_z_ LPCSTR pVarName); // Looks in the current effect only
  930. SGlobalVariable *FindVariableByName(_In_z_ LPCSTR pVarName);
  931. SVariable *FindVariableByNameWithParsing(_In_z_ LPCSTR pVarName);
  932. SConstantBuffer *FindCB(_In_z_ LPCSTR pName);
  933. void ReplaceCBReference(_In_ SConstantBuffer *pOldBufferBlock, _In_ ID3D11Buffer *pNewBuffer); // Used by user-managed CBs
  934. void ReplaceSamplerReference(_In_ SSamplerBlock *pOldSamplerBlock, _In_ ID3D11SamplerState *pNewSampler);
  935. void AddRefAllForCloning( _In_ CEffect* pEffectSource );
  936. HRESULT CopyMemberInterfaces( _In_ CEffect* pEffectSource );
  937. HRESULT CopyStringPool( _In_ CEffect* pEffectSource, _Inout_ CPointerMappingTable& mappingTable );
  938. HRESULT CopyTypePool( _In_ CEffect* pEffectSource, _Inout_ CPointerMappingTable& mappingTableTypes, _Inout_ CPointerMappingTable& mappingTableStrings );
  939. HRESULT CopyOptimizedTypePool( _In_ CEffect* pEffectSource, _Inout_ CPointerMappingTable& mappingTableTypes );
  940. HRESULT RecreateCBs();
  941. HRESULT FixupMemberInterface( _Inout_ SMember* pMember, _In_ CEffect* pEffectSource, _Inout_ CPointerMappingTable& mappingTableStrings );
  942. void ValidateIndex(_In_ uint32_t Elements);
  943. void IncrementTimer();
  944. void HandleLocalTimerRollover();
  945. friend struct SConstantBuffer;
  946. public:
  947. CEffect( uint32_t Flags = 0 );
  948. virtual ~CEffect();
  949. void ReleaseShaderRefection();
  950. // Initialize must be called after the effect is created
  951. HRESULT LoadEffect(_In_reads_bytes_(cbEffectBuffer) const void *pEffectBuffer, _In_ uint32_t cbEffectBuffer);
  952. // Once the effect is fully loaded, call BindToDevice to attach it to a device
  953. HRESULT BindToDevice(_In_ ID3D11Device *pDevice, _In_z_ LPCSTR srcName );
  954. Timer GetCurrentTime() const { return m_LocalTimer; }
  955. bool IsReflectionData(void *pData) const { return m_pReflection->m_Heap.IsInHeap(pData); }
  956. bool IsRuntimeData(void *pData) const { return m_Heap.IsInHeap(pData); }
  957. //////////////////////////////////////////////////////////////////////////
  958. // Public interface
  959. // IUnknown
  960. STDMETHOD(QueryInterface)(REFIID iid, _COM_Outptr_ LPVOID *ppv) override;
  961. STDMETHOD_(ULONG, AddRef)() override;
  962. STDMETHOD_(ULONG, Release)() override;
  963. // ID3DX11Effect
  964. STDMETHOD_(bool, IsValid)() override { return true; }
  965. STDMETHOD(GetDevice)(_Outptr_ ID3D11Device** ppDevice) override;
  966. STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_DESC *pDesc) override;
  967. STDMETHOD_(ID3DX11EffectConstantBuffer*, GetConstantBufferByIndex)(_In_ uint32_t Index) override;
  968. STDMETHOD_(ID3DX11EffectConstantBuffer*, GetConstantBufferByName)(_In_z_ LPCSTR Name) override;
  969. STDMETHOD_(ID3DX11EffectVariable*, GetVariableByIndex)(_In_ uint32_t Index) override;
  970. STDMETHOD_(ID3DX11EffectVariable*, GetVariableByName)(_In_z_ LPCSTR Name) override;
  971. STDMETHOD_(ID3DX11EffectVariable*, GetVariableBySemantic)(_In_z_ LPCSTR Semantic) override;
  972. STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByIndex)(_In_ uint32_t Index) override;
  973. STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByName)(_In_z_ LPCSTR Name) override;
  974. STDMETHOD_(ID3DX11EffectGroup*, GetGroupByIndex)(_In_ uint32_t Index) override;
  975. STDMETHOD_(ID3DX11EffectGroup*, GetGroupByName)(_In_z_ LPCSTR Name) override;
  976. STDMETHOD_(ID3D11ClassLinkage*, GetClassLinkage)() override;
  977. STDMETHOD(CloneEffect)(_In_ uint32_t Flags, _Outptr_ ID3DX11Effect** ppClonedEffect) override;
  978. STDMETHOD(Optimize)() override;
  979. STDMETHOD_(bool, IsOptimized)() override;
  980. //////////////////////////////////////////////////////////////////////////
  981. // New reflection helpers
  982. ID3DX11EffectType * CreatePooledSingleElementTypeInterface(_In_ SType *pType);
  983. ID3DX11EffectVariable * CreatePooledVariableMemberInterface(_In_ TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity,
  984. _In_ const SVariable *pMember,
  985. _In_ const UDataPointer Data, _In_ bool IsSingleElement, _In_ uint32_t Index);
  986. };
  987. }
  988. #pragma warning(pop)