1//--------------------------------------------------------------------------------------
2// File: EffectVariable.inl
3//
4// Direct3D 11 Effects Variable reflection template
5// These templates define the many Effect variable types.
6//
7// Copyright (c) Microsoft Corporation. All rights reserved.
8// Licensed under the MIT License.
9//
10// http://go.microsoft.com/fwlink/p/?LinkId=271568
11//--------------------------------------------------------------------------------------
12
13#pragma warning(push)
14#pragma warning(disable : 4127)
15
16//////////////////////////////////////////////////////////////////////////
17// Invalid variable forward defines
18//////////////////////////////////////////////////////////////////////////
19
20struct SEffectInvalidScalarVariable;
21struct SEffectInvalidVectorVariable;
22struct SEffectInvalidMatrixVariable;
23struct SEffectInvalidStringVariable;
24struct SEffectInvalidClassInstanceVariable;
25struct SEffectInvalidInterfaceVariable;
26struct SEffectInvalidShaderResourceVariable;
27struct SEffectInvalidUnorderedAccessViewVariable;
28struct SEffectInvalidRenderTargetViewVariable;
29struct SEffectInvalidDepthStencilViewVariable;
30struct SEffectInvalidConstantBuffer;
31struct SEffectInvalidShaderVariable;
32struct SEffectInvalidBlendVariable;
33struct SEffectInvalidDepthStencilVariable;
34struct SEffectInvalidRasterizerVariable;
35struct SEffectInvalidSamplerVariable;
36struct SEffectInvalidTechnique;
37struct SEffectInvalidPass;
38struct SEffectInvalidType;
39
40extern SEffectInvalidScalarVariable g_InvalidScalarVariable;
41extern SEffectInvalidVectorVariable g_InvalidVectorVariable;
42extern SEffectInvalidMatrixVariable g_InvalidMatrixVariable;
43extern SEffectInvalidStringVariable g_InvalidStringVariable;
44extern SEffectInvalidClassInstanceVariable g_InvalidClassInstanceVariable;
45extern SEffectInvalidInterfaceVariable g_InvalidInterfaceVariable;
46extern SEffectInvalidShaderResourceVariable g_InvalidShaderResourceVariable;
47extern SEffectInvalidUnorderedAccessViewVariable g_InvalidUnorderedAccessViewVariable;
48extern SEffectInvalidRenderTargetViewVariable g_InvalidRenderTargetViewVariable;
49extern SEffectInvalidDepthStencilViewVariable g_InvalidDepthStencilViewVariable;
50extern SEffectInvalidConstantBuffer g_InvalidConstantBuffer;
51extern SEffectInvalidShaderVariable g_InvalidShaderVariable;
52extern SEffectInvalidBlendVariable g_InvalidBlendVariable;
53extern SEffectInvalidDepthStencilVariable g_InvalidDepthStencilVariable;
54extern SEffectInvalidRasterizerVariable g_InvalidRasterizerVariable;
55extern SEffectInvalidSamplerVariable g_InvalidSamplerVariable;
56extern SEffectInvalidTechnique g_InvalidTechnique;
57extern SEffectInvalidPass g_InvalidPass;
58extern SEffectInvalidType g_InvalidType;
59
60enum ETemplateVarType
61{
62    ETVT_Bool,
63    ETVT_Int,
64    ETVT_Float,
65    ETVT_bool
66};
67
68//////////////////////////////////////////////////////////////////////////
69// Invalid effect variable struct definitions
70//////////////////////////////////////////////////////////////////////////
71
72struct SEffectInvalidType : public ID3DX11EffectType
73{
74    STDMETHOD_(bool, IsValid)() override { return false; }
75    STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
76    STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidType; }
77    STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidType; }
78    STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(_In_z_ LPCSTR Semantic) override { UNREFERENCED_PARAMETER(Semantic); return &g_InvalidType; }
79    STDMETHOD_(LPCSTR, GetMemberName)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return nullptr; }
80    STDMETHOD_(LPCSTR, GetMemberSemantic)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return nullptr; }
81    IUNKNOWN_IMP(SEffectInvalidType, ID3DX11EffectType, IUnknown);
82};
83
84template<typename IBaseInterface>
85struct TEffectInvalidVariable : public IBaseInterface
86{
87public:
88    STDMETHOD_(bool, IsValid)() override { return false; }
89    STDMETHOD_(ID3DX11EffectType*, GetType)() override { return &g_InvalidType; }
90    STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
91
92    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidScalarVariable; }
93    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidScalarVariable; }
94
95    STDMETHOD_(ID3DX11EffectVariable*, GetMemberByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidScalarVariable; }
96    STDMETHOD_(ID3DX11EffectVariable*, GetMemberByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidScalarVariable; }
97    STDMETHOD_(ID3DX11EffectVariable*, GetMemberBySemantic)(_In_z_ LPCSTR Semantic) override { UNREFERENCED_PARAMETER(Semantic); return &g_InvalidScalarVariable; }
98
99    STDMETHOD_(ID3DX11EffectVariable*, GetElement)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidScalarVariable; }
100
101    STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)() override { return &g_InvalidConstantBuffer; }
102
103    STDMETHOD_(ID3DX11EffectScalarVariable*, AsScalar)() override { return &g_InvalidScalarVariable; }
104    STDMETHOD_(ID3DX11EffectVectorVariable*, AsVector)() override { return &g_InvalidVectorVariable; }
105    STDMETHOD_(ID3DX11EffectMatrixVariable*, AsMatrix)() override { return &g_InvalidMatrixVariable; }
106    STDMETHOD_(ID3DX11EffectStringVariable*, AsString)() override { return &g_InvalidStringVariable; }
107    STDMETHOD_(ID3DX11EffectClassInstanceVariable*, AsClassInstance)() override { return &g_InvalidClassInstanceVariable; }
108    STDMETHOD_(ID3DX11EffectInterfaceVariable*, AsInterface)() override { return &g_InvalidInterfaceVariable; }
109    STDMETHOD_(ID3DX11EffectShaderResourceVariable*, AsShaderResource)() override { return &g_InvalidShaderResourceVariable; }
110    STDMETHOD_(ID3DX11EffectUnorderedAccessViewVariable*, AsUnorderedAccessView)() override { return &g_InvalidUnorderedAccessViewVariable; }
111    STDMETHOD_(ID3DX11EffectRenderTargetViewVariable*, AsRenderTargetView)() override { return &g_InvalidRenderTargetViewVariable; }
112    STDMETHOD_(ID3DX11EffectDepthStencilViewVariable*, AsDepthStencilView)() override { return &g_InvalidDepthStencilViewVariable; }
113    STDMETHOD_(ID3DX11EffectConstantBuffer*, AsConstantBuffer)() override { return &g_InvalidConstantBuffer; }
114    STDMETHOD_(ID3DX11EffectShaderVariable*, AsShader)() override { return &g_InvalidShaderVariable; }
115    STDMETHOD_(ID3DX11EffectBlendVariable*, AsBlend)() override { return &g_InvalidBlendVariable; }
116    STDMETHOD_(ID3DX11EffectDepthStencilVariable*, AsDepthStencil)() override { return &g_InvalidDepthStencilVariable; }
117    STDMETHOD_(ID3DX11EffectRasterizerVariable*, AsRasterizer)() override { return &g_InvalidRasterizerVariable; }
118    STDMETHOD_(ID3DX11EffectSamplerVariable*, AsSampler)() override { return &g_InvalidSamplerVariable; }
119
120    STDMETHOD(SetRawValue)(_In_reads_bytes_(Count) const void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
121        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
122    STDMETHOD(GetRawValue)(_Out_writes_bytes_(Count) void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
123        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
124};
125
126struct SEffectInvalidScalarVariable : public TEffectInvalidVariable<ID3DX11EffectScalarVariable>
127{
128public:
129
130    STDMETHOD(SetFloat)(_In_ const float Value) override { UNREFERENCED_PARAMETER(Value); return E_FAIL; }
131    STDMETHOD(GetFloat)(_Out_ float *pValue) override { UNREFERENCED_PARAMETER(pValue); return E_FAIL; }
132
133    STDMETHOD(SetFloatArray)(_In_reads_(Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
134        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
135    STDMETHOD(GetFloatArray)(_Out_writes_(Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
136        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
137
138    STDMETHOD(SetInt)(_In_ const int Value) override { UNREFERENCED_PARAMETER(Value); return E_FAIL; }
139    STDMETHOD(GetInt)(_Out_ int *pValue) override { UNREFERENCED_PARAMETER(pValue); return E_FAIL; }
140
141    STDMETHOD(SetIntArray)(_In_reads_(Count) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
142        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
143    STDMETHOD(GetIntArray)(_Out_writes_(Count) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
144        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
145
146    STDMETHOD(SetBool)(_In_ const bool Value) override { UNREFERENCED_PARAMETER(Value); return E_FAIL; }
147    STDMETHOD(GetBool)(_Out_ bool *pValue) override { UNREFERENCED_PARAMETER(pValue); return E_FAIL; }
148
149    STDMETHOD(SetBoolArray)(_In_reads_(Count) const bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
150        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
151    STDMETHOD(GetBoolArray)(_Out_writes_(Count) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
152        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
153
154    IUNKNOWN_IMP(SEffectInvalidScalarVariable, ID3DX11EffectScalarVariable, ID3DX11EffectVariable);
155};
156
157
158struct SEffectInvalidVectorVariable : public TEffectInvalidVariable<ID3DX11EffectVectorVariable>
159{
160public:
161    STDMETHOD(SetFloatVector)(_In_reads_(4) const float *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; };
162    STDMETHOD(SetIntVector)(_In_reads_(4) const int *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; };
163    STDMETHOD(SetBoolVector)(_In_reads_(4) const bool *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; };
164
165    STDMETHOD(GetFloatVector)(_Out_writes_(4) float *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; };
166    STDMETHOD(GetIntVector)(_Out_writes_(4) int *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; };
167    STDMETHOD(GetBoolVector)(_Out_writes_(4) bool *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; };
168
169    STDMETHOD(SetBoolVectorArray) (_In_reads_(4*Count) const bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
170        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; };
171    STDMETHOD(SetIntVectorArray)  (_In_reads_(4*Count) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
172        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; };
173    STDMETHOD(SetFloatVectorArray)(_In_reads_(4*Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
174        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; };
175
176    STDMETHOD(GetBoolVectorArray) (_Out_writes_(4*Count) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
177        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; };
178    STDMETHOD(GetIntVectorArray)  (_Out_writes_(4*Count) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
179        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; };
180    STDMETHOD(GetFloatVectorArray)(_Out_writes_(4*Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
181        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; };
182
183    IUNKNOWN_IMP(SEffectInvalidVectorVariable, ID3DX11EffectVectorVariable, ID3DX11EffectVariable);
184};
185
186struct SEffectInvalidMatrixVariable : public TEffectInvalidVariable<ID3DX11EffectMatrixVariable>
187{
188public:
189
190    STDMETHOD(SetMatrix)(_In_reads_(16) const float *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; }
191    STDMETHOD(GetMatrix)(_Out_writes_(16) float *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; }
192
193    STDMETHOD(SetMatrixArray)(_In_reads_(16*Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
194        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
195    STDMETHOD(GetMatrixArray)(_Out_writes_(16*Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
196        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
197
198    STDMETHOD(SetMatrixPointerArray)(_In_reads_(16*Count) const float **ppData, _In_ uint32_t Offset, _In_ uint32_t Count) override
199        { UNREFERENCED_PARAMETER(ppData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
200    STDMETHOD(GetMatrixPointerArray)(_Out_writes_(16*Count) float **ppData, _In_ uint32_t Offset, _In_ uint32_t Count) override
201        { UNREFERENCED_PARAMETER(ppData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
202
203    STDMETHOD(SetMatrixTranspose)(_In_reads_(16) const float *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; }
204    STDMETHOD(GetMatrixTranspose)(_Out_writes_(16) float *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; }
205
206    STDMETHOD(SetMatrixTransposeArray)(_In_reads_(16*Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
207        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
208    STDMETHOD(GetMatrixTransposeArray)(_Out_writes_(16*Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
209        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
210
211    STDMETHOD(SetMatrixTransposePointerArray)(_In_reads_(16*Count) const float **ppData, _In_ uint32_t Offset, _In_ uint32_t Count) override
212        { UNREFERENCED_PARAMETER(ppData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
213    STDMETHOD(GetMatrixTransposePointerArray)(_Out_writes_(16*Count) float **ppData, _In_ uint32_t Offset, _In_ uint32_t Count) override
214        { UNREFERENCED_PARAMETER(ppData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
215
216    IUNKNOWN_IMP(SEffectInvalidMatrixVariable, ID3DX11EffectMatrixVariable, ID3DX11EffectVariable);
217};
218
219struct SEffectInvalidStringVariable : public TEffectInvalidVariable<ID3DX11EffectStringVariable>
220{
221public:
222
223    STDMETHOD(GetString)(_Outptr_result_z_ LPCSTR *ppString) override { UNREFERENCED_PARAMETER(ppString); return E_FAIL; }
224    STDMETHOD(GetStringArray)(_Out_writes_(Count) LPCSTR *ppStrings, _In_ uint32_t Offset, _In_ uint32_t Count) override
225        { UNREFERENCED_PARAMETER(ppStrings); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
226
227    IUNKNOWN_IMP(SEffectInvalidStringVariable, ID3DX11EffectStringVariable, ID3DX11EffectVariable);
228};
229
230struct SEffectInvalidClassInstanceVariable : public TEffectInvalidVariable<ID3DX11EffectClassInstanceVariable>
231{
232public:
233
234    STDMETHOD(GetClassInstance)(_Outptr_ ID3D11ClassInstance **ppClassInstance) override { UNREFERENCED_PARAMETER(ppClassInstance); return E_FAIL; }
235
236    IUNKNOWN_IMP(SEffectInvalidClassInstanceVariable, ID3DX11EffectClassInstanceVariable, ID3DX11EffectVariable);
237};
238
239
240struct SEffectInvalidInterfaceVariable : public TEffectInvalidVariable<ID3DX11EffectInterfaceVariable>
241{
242public:
243
244    STDMETHOD(SetClassInstance)(_In_ ID3DX11EffectClassInstanceVariable *pEffectClassInstance) override
245        { UNREFERENCED_PARAMETER(pEffectClassInstance); return E_FAIL; }
246    STDMETHOD(GetClassInstance)(_Outptr_ ID3DX11EffectClassInstanceVariable **ppEffectClassInstance) override
247        { UNREFERENCED_PARAMETER(ppEffectClassInstance); return E_FAIL; }
248
249    IUNKNOWN_IMP(SEffectInvalidInterfaceVariable, ID3DX11EffectInterfaceVariable, ID3DX11EffectVariable);
250};
251
252
253struct SEffectInvalidShaderResourceVariable : public TEffectInvalidVariable<ID3DX11EffectShaderResourceVariable>
254{
255public:
256
257    STDMETHOD(SetResource)(_In_ ID3D11ShaderResourceView *pResource) override { UNREFERENCED_PARAMETER(pResource); return E_FAIL; }
258    STDMETHOD(GetResource)(_Outptr_ ID3D11ShaderResourceView **ppResource) override { UNREFERENCED_PARAMETER(ppResource); return E_FAIL; }
259
260    STDMETHOD(SetResourceArray)(_In_reads_(Count) ID3D11ShaderResourceView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
261        { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
262    STDMETHOD(GetResourceArray)(_Out_writes_(Count) ID3D11ShaderResourceView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
263        { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
264
265    IUNKNOWN_IMP(SEffectInvalidShaderResourceVariable, ID3DX11EffectShaderResourceVariable, ID3DX11EffectVariable);
266};
267
268
269struct SEffectInvalidUnorderedAccessViewVariable : public TEffectInvalidVariable<ID3DX11EffectUnorderedAccessViewVariable>
270{
271public:
272
273    STDMETHOD(SetUnorderedAccessView)(_In_ ID3D11UnorderedAccessView *pResource) override { UNREFERENCED_PARAMETER(pResource); return E_FAIL; }
274    STDMETHOD(GetUnorderedAccessView)(_Outptr_ ID3D11UnorderedAccessView **ppResource) override { UNREFERENCED_PARAMETER(ppResource); return E_FAIL; }
275
276    STDMETHOD(SetUnorderedAccessViewArray)(_In_reads_(Count) ID3D11UnorderedAccessView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
277        { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
278    STDMETHOD(GetUnorderedAccessViewArray)(_Out_writes_(Count) ID3D11UnorderedAccessView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
279        { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
280
281    IUNKNOWN_IMP(SEffectInvalidUnorderedAccessViewVariable, ID3DX11EffectUnorderedAccessViewVariable, ID3DX11EffectVariable);
282};
283
284
285struct SEffectInvalidRenderTargetViewVariable : public TEffectInvalidVariable<ID3DX11EffectRenderTargetViewVariable>
286{
287public:
288
289    STDMETHOD(SetRenderTarget)(_In_ ID3D11RenderTargetView *pResource) override { UNREFERENCED_PARAMETER(pResource); return E_FAIL; }
290    STDMETHOD(GetRenderTarget)(_Outptr_ ID3D11RenderTargetView **ppResource) override { UNREFERENCED_PARAMETER(ppResource); return E_FAIL; }
291
292    STDMETHOD(SetRenderTargetArray)(_In_reads_(Count) ID3D11RenderTargetView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
293        { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
294    STDMETHOD(GetRenderTargetArray)(_Out_writes_(Count) ID3D11RenderTargetView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
295        { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
296
297    IUNKNOWN_IMP(SEffectInvalidRenderTargetViewVariable, ID3DX11EffectRenderTargetViewVariable, ID3DX11EffectVariable);
298};
299
300
301struct SEffectInvalidDepthStencilViewVariable : public TEffectInvalidVariable<ID3DX11EffectDepthStencilViewVariable>
302{
303public:
304
305    STDMETHOD(SetDepthStencil)(_In_ ID3D11DepthStencilView *pResource) override { UNREFERENCED_PARAMETER(pResource); return E_FAIL; }
306    STDMETHOD(GetDepthStencil)(_Outptr_ ID3D11DepthStencilView **ppResource) override { UNREFERENCED_PARAMETER(ppResource); return E_FAIL; }
307
308    STDMETHOD(SetDepthStencilArray)(_In_reads_(Count) ID3D11DepthStencilView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
309        { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
310    STDMETHOD(GetDepthStencilArray)(_Out_writes_(Count) ID3D11DepthStencilView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
311        { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
312
313    IUNKNOWN_IMP(SEffectInvalidDepthStencilViewVariable, ID3DX11EffectDepthStencilViewVariable, ID3DX11EffectVariable);
314};
315
316
317struct SEffectInvalidConstantBuffer : public TEffectInvalidVariable<ID3DX11EffectConstantBuffer>
318{
319public:
320
321    STDMETHOD(SetConstantBuffer)(_In_ ID3D11Buffer *pConstantBuffer) override { UNREFERENCED_PARAMETER(pConstantBuffer); return E_FAIL; }
322    STDMETHOD(GetConstantBuffer)(_Outptr_ ID3D11Buffer **ppConstantBuffer) override { UNREFERENCED_PARAMETER(ppConstantBuffer); return E_FAIL; }
323    STDMETHOD(UndoSetConstantBuffer)() override { return E_FAIL; }
324
325    STDMETHOD(SetTextureBuffer)(_In_ ID3D11ShaderResourceView *pTextureBuffer) override { UNREFERENCED_PARAMETER(pTextureBuffer); return E_FAIL; }
326    STDMETHOD(GetTextureBuffer)(_Outptr_ ID3D11ShaderResourceView **ppTextureBuffer) override { UNREFERENCED_PARAMETER(ppTextureBuffer); return E_FAIL; }
327    STDMETHOD(UndoSetTextureBuffer)() override { return E_FAIL; }
328
329    IUNKNOWN_IMP(SEffectInvalidConstantBuffer, ID3DX11EffectConstantBuffer, ID3DX11EffectVariable);
330};
331
332struct SEffectInvalidShaderVariable : public TEffectInvalidVariable<ID3DX11EffectShaderVariable>
333{
334public:
335
336    STDMETHOD(GetShaderDesc)(_In_ uint32_t ShaderIndex, _Out_ D3DX11_EFFECT_SHADER_DESC *pDesc) override
337        { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
338
339    STDMETHOD(GetVertexShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11VertexShader **ppVS) override
340        { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(ppVS); return E_FAIL; }
341    STDMETHOD(GetGeometryShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11GeometryShader **ppGS) override
342        { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(ppGS); return E_FAIL; }
343    STDMETHOD(GetPixelShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11PixelShader **ppPS) override
344        { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(ppPS); return E_FAIL; }
345    STDMETHOD(GetHullShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11HullShader **ppHS) override
346        { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(ppHS); return E_FAIL; }
347    STDMETHOD(GetDomainShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11DomainShader **ppDS) override
348        { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(ppDS); return E_FAIL; }
349    STDMETHOD(GetComputeShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11ComputeShader **ppCS) override
350        { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(ppCS); return E_FAIL; }
351
352    STDMETHOD(GetInputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override
353        { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(Element); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
354    STDMETHOD(GetOutputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override
355        { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(Element); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
356    STDMETHOD(GetPatchConstantSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override
357        { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(Element); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
358
359    IUNKNOWN_IMP(SEffectInvalidShaderVariable, ID3DX11EffectShaderVariable, ID3DX11EffectVariable);
360};
361
362struct SEffectInvalidBlendVariable : public TEffectInvalidVariable<ID3DX11EffectBlendVariable>
363{
364public:
365
366    STDMETHOD(GetBlendState)(_In_ uint32_t Index, _Outptr_ ID3D11BlendState **ppState) override
367        { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(ppState); return E_FAIL; }
368    STDMETHOD(SetBlendState)(_In_ uint32_t Index, _In_ ID3D11BlendState *pState) override
369        { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pState); return E_FAIL; }
370    STDMETHOD(UndoSetBlendState)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return E_FAIL; }
371    STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_BLEND_DESC *pDesc) override
372        { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
373
374    IUNKNOWN_IMP(SEffectInvalidBlendVariable, ID3DX11EffectBlendVariable, ID3DX11EffectVariable);
375};
376
377struct SEffectInvalidDepthStencilVariable : public TEffectInvalidVariable<ID3DX11EffectDepthStencilVariable>
378{
379public:
380
381    STDMETHOD(GetDepthStencilState)(_In_ uint32_t Index, _Outptr_ ID3D11DepthStencilState **ppState) override
382        { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(ppState); return E_FAIL; }
383    STDMETHOD(SetDepthStencilState)(_In_ uint32_t Index, _In_ ID3D11DepthStencilState *pState) override
384        { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pState); return E_FAIL; }
385    STDMETHOD(UndoSetDepthStencilState)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return E_FAIL; }
386    STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_DEPTH_STENCIL_DESC *pDesc) override
387        { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
388
389    IUNKNOWN_IMP(SEffectInvalidDepthStencilVariable, ID3DX11EffectDepthStencilVariable, ID3DX11EffectVariable);
390};
391
392struct SEffectInvalidRasterizerVariable : public TEffectInvalidVariable<ID3DX11EffectRasterizerVariable>
393{
394public:
395
396    STDMETHOD(GetRasterizerState)(_In_ uint32_t Index, _Outptr_ ID3D11RasterizerState **ppState) override
397        { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(ppState); return E_FAIL; }
398    STDMETHOD(SetRasterizerState)(_In_ uint32_t Index, _In_ ID3D11RasterizerState *pState) override
399        { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pState); return E_FAIL; }
400    STDMETHOD(UndoSetRasterizerState)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return E_FAIL; }
401    STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_RASTERIZER_DESC *pDesc) override
402        { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
403
404    IUNKNOWN_IMP(SEffectInvalidRasterizerVariable, ID3DX11EffectRasterizerVariable, ID3DX11EffectVariable);
405};
406
407struct SEffectInvalidSamplerVariable : public TEffectInvalidVariable<ID3DX11EffectSamplerVariable>
408{
409public:
410
411    STDMETHOD(GetSampler)(_In_ uint32_t Index, _Outptr_ ID3D11SamplerState **ppSampler) override
412        { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(ppSampler); return E_FAIL; }
413    STDMETHOD(SetSampler)(_In_ uint32_t Index, _In_ ID3D11SamplerState *pSampler) override
414        { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pSampler); return E_FAIL; }
415    STDMETHOD(UndoSetSampler)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return E_FAIL; }
416    STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_SAMPLER_DESC *pDesc) override
417        { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
418
419    IUNKNOWN_IMP(SEffectInvalidSamplerVariable, ID3DX11EffectSamplerVariable, ID3DX11EffectVariable);
420};
421
422struct SEffectInvalidPass : public ID3DX11EffectPass
423{
424public:
425    STDMETHOD_(bool, IsValid)() override { return false; }
426    STDMETHOD(GetDesc)(_Out_ D3DX11_PASS_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
427
428    STDMETHOD(GetVertexShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
429    STDMETHOD(GetGeometryShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
430    STDMETHOD(GetPixelShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
431    STDMETHOD(GetHullShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
432    STDMETHOD(GetDomainShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
433    STDMETHOD(GetComputeShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
434
435    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidScalarVariable; }
436    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidScalarVariable; }
437
438    STDMETHOD(Apply)(_In_ uint32_t Flags, _In_ ID3D11DeviceContext* pContext) override
439        { UNREFERENCED_PARAMETER(Flags); UNREFERENCED_PARAMETER(pContext); return E_FAIL; }
440    STDMETHOD(ComputeStateBlockMask)(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask) override { UNREFERENCED_PARAMETER(pStateBlockMask); return E_FAIL; }
441
442    IUNKNOWN_IMP(SEffectInvalidPass, ID3DX11EffectPass, IUnknown);
443};
444
445struct SEffectInvalidTechnique : public ID3DX11EffectTechnique
446{
447public:
448    STDMETHOD_(bool, IsValid)() override { return false; }
449    STDMETHOD(GetDesc)(_Out_ D3DX11_TECHNIQUE_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
450
451    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidScalarVariable; }
452    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidScalarVariable; }
453
454    STDMETHOD_(ID3DX11EffectPass*, GetPassByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidPass; }
455    STDMETHOD_(ID3DX11EffectPass*, GetPassByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidPass; }
456
457    STDMETHOD(ComputeStateBlockMask)(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask) override { UNREFERENCED_PARAMETER(pStateBlockMask); return E_FAIL; }
458
459    IUNKNOWN_IMP(SEffectInvalidTechnique, ID3DX11EffectTechnique, IUnknown);
460};
461
462struct SEffectInvalidGroup : public ID3DX11EffectGroup
463{
464public:
465    STDMETHOD_(bool, IsValid)() override { return false; }
466    STDMETHOD(GetDesc)(_Out_ D3DX11_GROUP_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
467
468    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidScalarVariable; }
469    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidScalarVariable; }
470
471    STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidTechnique; }
472    STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidTechnique; }
473
474    IUNKNOWN_IMP(SEffectInvalidGroup, ID3DX11EffectGroup, IUnknown);
475};
476
477//////////////////////////////////////////////////////////////////////////
478// Helper routines
479//////////////////////////////////////////////////////////////////////////
480
481// This is an annoying warning that pops up in retail builds because
482// the code that jumps to "lExit" is conditionally not compiled.
483// The only alternative is more #ifdefs in every function
484#pragma warning( disable : 4102 ) // 'label' : unreferenced label
485
486#define VERIFYPARAMETER(x) \
487{ if (!(x)) { DPF(0, "%s: Parameter " #x " was nullptr.", pFuncName); \
488    __BREAK_ON_FAIL; hr = E_INVALIDARG; goto lExit; } }
489
490static HRESULT AnnotationInvalidSetCall(LPCSTR pFuncName)
491{
492    DPF(0, "%s: Annotations are readonly", pFuncName);
493    return D3DERR_INVALIDCALL;
494}
495
496static HRESULT ObjectSetRawValue()
497{
498    DPF(0, "ID3DX11EffectVariable::SetRawValue: Objects do not support ths call; please use the specific object accessors instead.");
499    return D3DERR_INVALIDCALL;
500}
501
502static HRESULT ObjectGetRawValue()
503{
504    DPF(0, "ID3DX11EffectVariable::GetRawValue: Objects do not support ths call; please use the specific object accessors instead.");
505    return D3DERR_INVALIDCALL;
506}
507
508ID3DX11EffectConstantBuffer * NoParentCB();
509
510ID3DX11EffectVariable * GetAnnotationByIndexHelper(_In_z_ const char *pClassName, _In_ uint32_t Index,
511                                                   _In_ uint32_t  AnnotationCount, _In_reads_(AnnotationCount) SAnnotation *pAnnotations);
512
513ID3DX11EffectVariable * GetAnnotationByNameHelper(_In_z_ const char *pClassName, _In_z_ LPCSTR Name,
514                                                   _In_ uint32_t  AnnotationCount, _In_reads_(AnnotationCount) SAnnotation *pAnnotations);
515
516template<typename SVarType>
517_Success_(return)
518bool GetVariableByIndexHelper(_In_ uint32_t Index, _In_ uint32_t  VariableCount, _In_reads_(VariableCount) SVarType *pVariables,
519                              _In_opt_ uint8_t *pBaseAddress, _Outptr_ SVarType **ppMember, _Outptr_ void **ppDataPtr)
520{
521    static LPCSTR pFuncName = "ID3DX11EffectVariable::GetMemberByIndex";
522
523    if (Index >= VariableCount)
524    {
525        DPF(0, "%s: Invalid index (%u, total: %u)", pFuncName, Index, VariableCount);
526        return false;
527    }
528
529    *ppMember = pVariables + Index;
530    *ppDataPtr = pBaseAddress + (*ppMember)->Data.Offset;
531    return true;
532}
533
534template<typename SVarType>
535_Success_(return)
536bool GetVariableByNameHelper(_In_z_ LPCSTR Name, _In_ uint32_t  VariableCount, _In_reads_(VariableCount) SVarType *pVariables,
537                             _In_opt_ uint8_t *pBaseAddress, _Outptr_ SVarType **ppMember, _Outptr_ void **ppDataPtr, _Out_ uint32_t* pIndex)
538{
539    static LPCSTR pFuncName = "ID3DX11EffectVariable::GetMemberByName";
540
541    if (nullptr == Name)
542    {
543        DPF(0, "%s: Parameter Name was nullptr.", pFuncName);
544        return false;
545    }
546
547    bool bHasSuper = false;
548
549    for (uint32_t i = 0; i < VariableCount; ++ i)
550    {
551        *ppMember = pVariables + i;
552        assert((*ppMember)->pName != 0);
553        _Analysis_assume_((*ppMember)->pName != 0);
554        if (strcmp((*ppMember)->pName, Name) == 0)
555        {
556            *ppDataPtr = pBaseAddress + (*ppMember)->Data.Offset;
557            *pIndex = i;
558            return true;
559        }
560        else if (i == 0 &&
561                 (*ppMember)->pName[0] == '$' &&
562                 strcmp((*ppMember)->pName, "$super") == 0)
563        {
564            bHasSuper = true;
565        }
566    }
567
568    if (bHasSuper)
569    {
570        SVarType* pSuper = pVariables;
571
572        return GetVariableByNameHelper<SVarType>(Name,
573                                                 pSuper->pType->StructType.Members,
574                                                 (SVarType*)pSuper->pType->StructType.pMembers,
575                                                 pBaseAddress + pSuper->Data.Offset,
576                                                 ppMember,
577                                                 ppDataPtr,
578                                                 pIndex);
579    }
580
581    DPF(0, "%s: Variable [%s] not found", pFuncName, Name);
582    return false;
583}
584
585template<typename SVarType>
586_Success_(return)
587bool GetVariableBySemanticHelper(_In_z_ LPCSTR Semantic, _In_ uint32_t  VariableCount, _In_reads_(VariableCount) SVarType *pVariables,
588                                 _In_opt_ uint8_t *pBaseAddress, _Outptr_ SVarType **ppMember, _Outptr_ void **ppDataPtr, _Out_ uint32_t* pIndex)
589{
590    static LPCSTR pFuncName = "ID3DX11EffectVariable::GetMemberBySemantic";
591
592    if (nullptr == Semantic)
593    {
594        DPF(0, "%s: Parameter Semantic was nullptr.", pFuncName);
595        return false;
596    }
597
598    for (uint32_t i = 0; i < VariableCount; ++ i)
599    {
600        *ppMember = pVariables + i;
601        if (nullptr != (*ppMember)->pSemantic &&
602            _stricmp((*ppMember)->pSemantic, Semantic) == 0)
603        {
604            *ppDataPtr = pBaseAddress + (*ppMember)->Data.Offset;
605            *pIndex = i;
606            return true;
607        }
608    }
609
610    DPF(0, "%s: Variable with semantic [%s] not found", pFuncName, Semantic);
611    return false;
612}
613
614inline bool AreBoundsValid(_In_ uint32_t Offset, _In_ uint32_t Count, _In_ const void *pData, _In_ const SType *pType, _In_ uint32_t  TotalUnpackedSize)
615{
616    if (Count == 0) return true;
617    uint32_t  singleElementSize = pType->GetTotalUnpackedSize(true);
618    assert(singleElementSize <= pType->Stride);
619
620    return ((Offset + Count >= Offset) &&
621        ((Offset + Count) < ((uint32_t)-1) / pType->Stride) &&
622        (Count * pType->Stride + (uint8_t*)pData >= (uint8_t*)pData) &&
623        ((Offset + Count - 1) * pType->Stride + singleElementSize <= TotalUnpackedSize));
624}
625
626// Note that the branches in this code is based on template parameters and will be compiled out
627template<ETemplateVarType SourceType, ETemplateVarType DestType, typename SRC_TYPE, bool ValidatePtr>
628__forceinline HRESULT CopyScalarValue(_In_ SRC_TYPE SrcValue, _Out_ void *pDest, _In_z_ const char *pFuncName)
629{
630    HRESULT hr = S_OK;
631#ifdef _DEBUG
632    if (ValidatePtr)
633        VERIFYPARAMETER(pDest);
634#else
635    UNREFERENCED_PARAMETER(pFuncName);
636#endif
637
638    switch (SourceType)
639    {
640    case ETVT_Bool:
641        switch (DestType)
642        {
643        case ETVT_Bool:
644            *(int*)pDest = (SrcValue != 0) ? -1 : 0;
645            break;
646
647        case ETVT_Int:
648            *(int*)pDest = SrcValue ? 1 : 0;
649            break;
650
651        case ETVT_Float:
652            *(float*)pDest = SrcValue ? 1.0f : 0.0f;
653            break;
654
655        case ETVT_bool:
656            *(bool*)pDest = (SrcValue != 0) ? true : false;
657            break;
658
659        default:
660            assert(0);
661        }
662        break;
663
664    case ETVT_Int:
665        switch (DestType)
666        {
667        case ETVT_Bool:
668            *(int*)pDest = (SrcValue != 0) ? -1 : 0;
669            break;
670
671        case ETVT_Int:
672            *(int*)pDest = (int) SrcValue;
673            break;
674
675        case ETVT_Float:
676            *(float*)pDest = (float)(SrcValue);
677            break;
678
679        case ETVT_bool:
680            *(bool*)pDest = (SrcValue != 0) ? true : false;
681            break;
682
683        default:
684            assert(0);
685        }
686        break;
687
688    case ETVT_Float:
689        switch (DestType)
690        {
691        case ETVT_Bool:
692            *(int*)pDest = (SrcValue != 0.0f) ? -1 : 0;
693            break;
694
695        case ETVT_Int:
696            *(int*)pDest = (int) (SrcValue);
697            break;
698
699        case ETVT_Float:
700            *(float*)pDest = (float) SrcValue;
701            break;
702
703        case ETVT_bool:
704            *(bool*)pDest = (SrcValue != 0.0f) ? true : false;
705            break;
706
707        default:
708            assert(0);
709        }
710        break;
711
712    case ETVT_bool:
713        switch (DestType)
714        {
715        case ETVT_Bool:
716            *(int*)pDest = SrcValue ? -1 : 0;
717            break;
718
719        case ETVT_Int:
720            *(int*)pDest = SrcValue ? 1 : 0;
721            break;
722
723        case ETVT_Float:
724            *(float*)pDest = SrcValue ? 1.0f : 0.0f;
725            break;
726
727        case ETVT_bool:
728            *(bool*)pDest = (SrcValue != 0) ? true : false;
729            break;
730
731        default:
732            assert(0);
733        }
734        break;
735
736    default:
737        assert(0);
738    }
739
740lExit:
741    return hr;
742}
743
744#pragma warning(push)
745#pragma warning( disable : 6103 )
746template<ETemplateVarType SourceType, ETemplateVarType DestType, typename SRC_TYPE, typename DEST_TYPE>
747inline HRESULT SetScalarArray(_In_reads_(Count) const SRC_TYPE *pSrcValues, _Out_writes_(Count) DEST_TYPE *pDestValues,
748                              _In_ uint32_t Offset, _In_ uint32_t Count,
749                              _In_ const SType *pType, _In_ uint32_t TotalUnpackedSize, _In_z_ const char *pFuncName)
750{
751    HRESULT hr = S_OK;
752
753#ifdef _DEBUG
754    VERIFYPARAMETER(pSrcValues);
755
756#pragma warning( suppress : 6001 )
757    if (!AreBoundsValid(Offset, Count, pSrcValues, pType, TotalUnpackedSize))
758    {
759        DPF(0, "%s: Invalid range specified", pFuncName);
760        VH(E_INVALIDARG);
761    }
762#else
763    UNREFERENCED_PARAMETER(TotalUnpackedSize);
764    UNREFERENCED_PARAMETER(pFuncName);
765#endif
766
767    uint32_t i, j, delta = pType->NumericType.IsPackedArray ? 1 : SType::c_ScalarsPerRegister;
768    pDestValues += Offset * delta;
769    for (i = 0, j = 0; j < Count; i += delta, ++ j)
770    {
771        // pDestValues[i] = (DEST_TYPE)pSrcValues[j];
772        CopyScalarValue<SourceType, DestType, SRC_TYPE, false>(pSrcValues[j], &pDestValues[i], "SetScalarArray");
773    }
774
775lExit:
776    return hr;
777}
778#pragma warning(pop)
779
780#pragma warning( disable : 6103 )
781template<ETemplateVarType SourceType, ETemplateVarType DestType, typename SRC_TYPE, typename DEST_TYPE>
782inline HRESULT GetScalarArray(_In_reads_(Count) SRC_TYPE *pSrcValues, _Out_writes_(Count) DEST_TYPE *pDestValues,
783                              _In_ uint32_t Offset, _In_ uint32_t Count,
784                              _In_ const SType *pType, _In_ uint32_t  TotalUnpackedSize, _In_z_ const char *pFuncName)
785{
786    HRESULT hr = S_OK;
787
788#ifdef _DEBUG
789    VERIFYPARAMETER(pDestValues);
790
791#pragma warning( suppress : 6001 )
792    if (!AreBoundsValid(Offset, Count, pDestValues, pType, TotalUnpackedSize))
793    {
794        DPF(0, "%s: Invalid range specified", pFuncName);
795        VH(E_INVALIDARG);
796    }
797#else
798    UNREFERENCED_PARAMETER(TotalUnpackedSize);
799    UNREFERENCED_PARAMETER(pFuncName);
800#endif
801
802    uint32_t i, j, delta = pType->NumericType.IsPackedArray ? 1 : SType::c_ScalarsPerRegister;
803    pSrcValues += Offset * delta;
804    for (i = 0, j = 0; j < Count; i += delta, ++ j)
805    {
806        // pDestValues[j] = (DEST_TYPE)pSrcValues[i];
807        CopyScalarValue<SourceType, DestType, SRC_TYPE, false>(pSrcValues[i], &pDestValues[j], "GetScalarArray");
808    }
809
810lExit:
811    return hr;
812}
813
814
815//////////////////////////////////////////////////////////////////////////
816// TVariable - implements type casting and member/element retrieval
817//////////////////////////////////////////////////////////////////////////
818
819// requires that IBaseInterface contain SVariable's fields and support ID3DX11EffectVariable
820template<typename IBaseInterface>
821struct TVariable : public IBaseInterface
822{
823    STDMETHOD_(bool, IsValid)() override { return true; }
824
825    STDMETHOD_(ID3DX11EffectVariable*, GetMemberByIndex)(_In_ uint32_t Index)
826    {
827        SVariable *pMember;
828        UDataPointer dataPtr;
829        TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity2 = GetTopLevelEntity();
830
831        if (((ID3DX11Effect*)pTopLevelEntity2->pEffect)->IsOptimized())
832        {
833            DPF(0, "ID3DX11EffectVariable::GetMemberByIndex: Cannot get members; effect has been Optimize()'ed");
834            return &g_InvalidScalarVariable;
835        }
836
837        if (pType->VarType != EVT_Struct)
838        {
839            DPF(0, "ID3DX11EffectVariable::GetMemberByIndex: Variable is not a structure");
840            return &g_InvalidScalarVariable;
841        }
842
843        if (!GetVariableByIndexHelper<SVariable>(Index, pType->StructType.Members, pType->StructType.pMembers,
844            Data.pNumeric, &pMember, &dataPtr.pGeneric))
845        {
846            return &g_InvalidScalarVariable;
847        }
848
849        return pTopLevelEntity2->pEffect->CreatePooledVariableMemberInterface(pTopLevelEntity2, pMember, dataPtr, false, Index);
850    }
851
852    STDMETHOD_(ID3DX11EffectVariable*, GetMemberByName)(_In_z_ LPCSTR Name)
853    {
854        SVariable *pMember;
855        UDataPointer dataPtr;
856        uint32_t index;
857        TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity2 = GetTopLevelEntity();
858
859        if (pTopLevelEntity2->pEffect->IsOptimized())
860        {
861            DPF(0, "ID3DX11EffectVariable::GetMemberByName: Cannot get members; effect has been Optimize()'ed");
862            return &g_InvalidScalarVariable;
863        }
864
865        if (pType->VarType != EVT_Struct)
866        {
867            DPF(0, "ID3DX11EffectVariable::GetMemberByName: Variable is not a structure");
868            return &g_InvalidScalarVariable;
869        }
870
871        if (!GetVariableByNameHelper<SVariable>(Name, pType->StructType.Members, pType->StructType.pMembers,
872            Data.pNumeric, &pMember, &dataPtr.pGeneric, &index))
873        {
874            return &g_InvalidScalarVariable;
875
876        }
877
878        return pTopLevelEntity2->pEffect->CreatePooledVariableMemberInterface(pTopLevelEntity2, pMember, dataPtr, false, index);
879    }
880
881    STDMETHOD_(ID3DX11EffectVariable*, GetMemberBySemantic)(_In_z_ LPCSTR Semantic)
882    {
883        SVariable *pMember;
884        UDataPointer dataPtr;
885        uint32_t index;
886        TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity2 = GetTopLevelEntity();
887
888        if (pTopLevelEntity2->pEffect->IsOptimized())
889        {
890            DPF(0, "ID3DX11EffectVariable::GetMemberBySemantic: Cannot get members; effect has been Optimize()'ed");
891            return &g_InvalidScalarVariable;
892        }
893
894        if (pType->VarType != EVT_Struct)
895        {
896            DPF(0, "ID3DX11EffectVariable::GetMemberBySemantic: Variable is not a structure");
897            return &g_InvalidScalarVariable;
898        }
899
900        if (!GetVariableBySemanticHelper<SVariable>(Semantic, pType->StructType.Members, pType->StructType.pMembers,
901            Data.pNumeric, &pMember, &dataPtr.pGeneric, &index))
902        {
903            return &g_InvalidScalarVariable;
904
905        }
906
907        return pTopLevelEntity2->pEffect->CreatePooledVariableMemberInterface(pTopLevelEntity2, pMember, dataPtr, false, index);
908    }
909
910    STDMETHOD_(ID3DX11EffectVariable*, GetElement)(_In_ uint32_t Index)
911    {
912        static LPCSTR pFuncName = "ID3DX11EffectVariable::GetElement";
913        TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity2 = GetTopLevelEntity();
914        UDataPointer dataPtr;
915
916        if (pTopLevelEntity2->pEffect->IsOptimized())
917        {
918            DPF(0, "ID3DX11EffectVariable::GetElement: Cannot get element; effect has been Optimize()'ed");
919            return &g_InvalidScalarVariable;
920        }
921
922        if (!IsArray())
923        {
924            DPF(0, "%s: This interface does not refer to an array", pFuncName);
925            return &g_InvalidScalarVariable;
926        }
927
928        if (Index >= pType->Elements)
929        {
930            DPF(0, "%s: Invalid element index (%u, total: %u)", pFuncName, Index, pType->Elements);
931            return &g_InvalidScalarVariable;
932        }
933
934        if (pType->BelongsInConstantBuffer())
935        {
936            dataPtr.pGeneric = Data.pNumeric + pType->Stride * Index;
937        }
938        else
939        {
940            dataPtr.pGeneric = GetBlockByIndex(pType->VarType, pType->ObjectType, Data.pGeneric, Index);
941            if (nullptr == dataPtr.pGeneric)
942            {
943                DPF(0, "%s: Internal error", pFuncName);
944                return &g_InvalidScalarVariable;
945            }
946        }
947
948        return pTopLevelEntity2->pEffect->CreatePooledVariableMemberInterface(pTopLevelEntity2, (SVariable *) this, dataPtr, true, Index);
949    }
950
951    STDMETHOD_(ID3DX11EffectScalarVariable*, AsScalar)()
952    {
953        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsScalar";
954
955        if (pType->VarType != EVT_Numeric ||
956            pType->NumericType.NumericLayout != ENL_Scalar)
957        {
958            DPF(0, "%s: Invalid typecast", pFuncName);
959            return &g_InvalidScalarVariable;
960        }
961
962        return (ID3DX11EffectScalarVariable *) this;
963    }
964
965    STDMETHOD_(ID3DX11EffectVectorVariable*, AsVector)()
966    {
967        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsVector";
968
969        if (pType->VarType != EVT_Numeric ||
970            pType->NumericType.NumericLayout != ENL_Vector)
971        {
972            DPF(0, "%s: Invalid typecast", pFuncName);
973            return &g_InvalidVectorVariable;
974        }
975
976        return (ID3DX11EffectVectorVariable *) this;
977    }
978
979    STDMETHOD_(ID3DX11EffectMatrixVariable*, AsMatrix)()
980    {
981        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsMatrix";
982
983        if (pType->VarType != EVT_Numeric ||
984            pType->NumericType.NumericLayout != ENL_Matrix)
985        {
986            DPF(0, "%s: Invalid typecast", pFuncName);
987            return &g_InvalidMatrixVariable;
988        }
989
990        return (ID3DX11EffectMatrixVariable *) this;
991    }
992
993    STDMETHOD_(ID3DX11EffectStringVariable*, AsString)()
994    {
995        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsString";
996
997        if (!pType->IsObjectType(EOT_String))
998        {
999            DPF(0, "%s: Invalid typecast", pFuncName);
1000            return &g_InvalidStringVariable;
1001        }
1002
1003        return (ID3DX11EffectStringVariable *) this;
1004    }
1005
1006    STDMETHOD_(ID3DX11EffectClassInstanceVariable*, AsClassInstance)()
1007    {
1008        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsClassInstance";
1009
1010        if (!pType->IsClassInstance() )
1011        {
1012            DPF(0, "%s: Invalid typecast", pFuncName);
1013            return &g_InvalidClassInstanceVariable;
1014        }
1015        else if( pMemberData == nullptr )
1016        {
1017            DPF(0, "%s: Non-global class instance variables (members of structs or classes) and class instances "
1018                   "inside tbuffers are not supported.", pFuncName );
1019            return &g_InvalidClassInstanceVariable;
1020        }
1021
1022        return (ID3DX11EffectClassInstanceVariable *) this;
1023    }
1024
1025    STDMETHOD_(ID3DX11EffectInterfaceVariable*, AsInterface)()
1026    {
1027        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsInterface";
1028
1029        if (!pType->IsInterface())
1030        {
1031            DPF(0, "%s: Invalid typecast", pFuncName);
1032            return &g_InvalidInterfaceVariable;
1033        }
1034
1035        return (ID3DX11EffectInterfaceVariable *) this;
1036    }
1037
1038    STDMETHOD_(ID3DX11EffectShaderResourceVariable*, AsShaderResource)()
1039    {
1040        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsShaderResource";
1041
1042        if (!pType->IsShaderResource())
1043        {
1044            DPF(0, "%s: Invalid typecast", pFuncName);
1045            return &g_InvalidShaderResourceVariable;
1046        }
1047
1048        return (ID3DX11EffectShaderResourceVariable *) this;
1049    }
1050
1051    STDMETHOD_(ID3DX11EffectUnorderedAccessViewVariable*, AsUnorderedAccessView)()
1052    {
1053        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsUnorderedAccessView";
1054
1055        if (!pType->IsUnorderedAccessView())
1056        {
1057            DPF(0, "%s: Invalid typecast", pFuncName);
1058            return &g_InvalidUnorderedAccessViewVariable;
1059        }
1060
1061        return (ID3DX11EffectUnorderedAccessViewVariable *) this;
1062    }
1063
1064    STDMETHOD_(ID3DX11EffectRenderTargetViewVariable*, AsRenderTargetView)()
1065    {
1066        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsRenderTargetView";
1067
1068        if (!pType->IsRenderTargetView())
1069        {
1070            DPF(0, "%s: Invalid typecast", pFuncName);
1071            return &g_InvalidRenderTargetViewVariable;
1072        }
1073
1074        return (ID3DX11EffectRenderTargetViewVariable *) this;
1075    }
1076
1077    STDMETHOD_(ID3DX11EffectDepthStencilViewVariable*, AsDepthStencilView)()
1078    {
1079        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsDepthStencilView";
1080
1081        if (!pType->IsDepthStencilView())
1082        {
1083            DPF(0, "%s: Invalid typecast", pFuncName);
1084            return &g_InvalidDepthStencilViewVariable;
1085        }
1086
1087        return (ID3DX11EffectDepthStencilViewVariable *) this;
1088    }
1089
1090    STDMETHOD_(ID3DX11EffectConstantBuffer*, AsConstantBuffer)()
1091    {
1092        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsConstantBuffer";
1093        DPF(0, "%s: Invalid typecast", pFuncName);
1094        return &g_InvalidConstantBuffer;
1095    }
1096
1097    STDMETHOD_(ID3DX11EffectShaderVariable*, AsShader)()
1098    {
1099        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsShader";
1100
1101        if (!pType->IsShader())
1102        {
1103            DPF(0, "%s: Invalid typecast", pFuncName);
1104            return &g_InvalidShaderVariable;
1105        }
1106
1107        return (ID3DX11EffectShaderVariable *) this;
1108    }
1109
1110    STDMETHOD_(ID3DX11EffectBlendVariable*, AsBlend)()
1111    {
1112        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsBlend";
1113
1114        if (!pType->IsObjectType(EOT_Blend))
1115        {
1116            DPF(0, "%s: Invalid typecast", pFuncName);
1117            return &g_InvalidBlendVariable;
1118        }
1119
1120        return (ID3DX11EffectBlendVariable *) this;
1121    }
1122
1123    STDMETHOD_(ID3DX11EffectDepthStencilVariable*, AsDepthStencil)()
1124    {
1125        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsDepthStencil";
1126
1127        if (!pType->IsObjectType(EOT_DepthStencil))
1128        {
1129            DPF(0, "%s: Invalid typecast", pFuncName);
1130            return &g_InvalidDepthStencilVariable;
1131        }
1132
1133        return (ID3DX11EffectDepthStencilVariable *) this;
1134    }
1135
1136    STDMETHOD_(ID3DX11EffectRasterizerVariable*, AsRasterizer)()
1137    {
1138        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsRasterizer";
1139
1140        if (!pType->IsObjectType(EOT_Rasterizer))
1141        {
1142            DPF(0, "%s: Invalid typecast", pFuncName);
1143            return &g_InvalidRasterizerVariable;
1144        }
1145
1146        return (ID3DX11EffectRasterizerVariable *) this;
1147    }
1148
1149    STDMETHOD_(ID3DX11EffectSamplerVariable*, AsSampler)()
1150    {
1151        static LPCSTR pFuncName = "ID3DX11EffectVariable::AsSampler";
1152
1153        if (!pType->IsSampler())
1154        {
1155            DPF(0, "%s: Invalid typecast", pFuncName);
1156            return &g_InvalidSamplerVariable;
1157        }
1158
1159        return (ID3DX11EffectSamplerVariable *) this;
1160    }
1161
1162    // Numeric variables should override this
1163    STDMETHOD(SetRawValue)(_In_reads_bytes_(Count) const void *pData, _In_ uint32_t Offset, _In_ uint32_t Count)
1164        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return ObjectSetRawValue(); }
1165    STDMETHOD(GetRawValue)(_Out_writes_(Count) void *pData, _In_ uint32_t Offset, _In_ uint32_t Count)
1166        { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return ObjectGetRawValue(); }
1167};
1168
1169//////////////////////////////////////////////////////////////////////////
1170// TTopLevelVariable - functionality for annotations and global variables
1171//////////////////////////////////////////////////////////////////////////
1172
1173template<typename IBaseInterface>
1174struct TTopLevelVariable : public SVariable, public IBaseInterface
1175{
1176    // Required to create member/element variable interfaces
1177    CEffect *pEffect;
1178
1179    CEffect* GetEffect()
1180    {
1181        return pEffect;
1182    }
1183
1184    TTopLevelVariable() noexcept :
1185        pEffect(nullptr)
1186    {
1187    }
1188
1189    uint32_t  GetTotalUnpackedSize()
1190    {
1191        return ((SType*)pType)->GetTotalUnpackedSize(false);
1192    }
1193
1194    STDMETHOD_(ID3DX11EffectType*, GetType)()
1195    {
1196        return (ID3DX11EffectType*)(SType*)pType;
1197    }
1198
1199    TTopLevelVariable<ID3DX11EffectVariable> * GetTopLevelEntity()
1200    {
1201        return (TTopLevelVariable<ID3DX11EffectVariable> *)this;
1202    }
1203
1204    bool IsArray()
1205    {
1206        return (pType->Elements > 0);
1207    }
1208
1209};
1210
1211//////////////////////////////////////////////////////////////////////////
1212// TMember - functionality for structure/array members of other variables
1213//////////////////////////////////////////////////////////////////////////
1214
1215template<typename IBaseInterface>
1216struct TMember : public SVariable, public IBaseInterface
1217{
1218    // Indicates that this is a single element of a containing array
1219    uint32_t                                    IsSingleElement : 1;
1220
1221    // Required to create member/element variable interfaces
1222    TTopLevelVariable<ID3DX11EffectVariable>    *pTopLevelEntity;
1223
1224    TMember() noexcept :
1225        IsSingleElement(false),
1226        pTopLevelEntity(nullptr)
1227    {
1228    }
1229
1230    CEffect* GetEffect()
1231    {
1232        return pTopLevelEntity->pEffect;
1233    }
1234
1235    uint32_t  GetTotalUnpackedSize()
1236    {
1237        return pType->GetTotalUnpackedSize(IsSingleElement);
1238    }
1239
1240    STDMETHOD_(ID3DX11EffectType*, GetType)() override
1241    {
1242        if (IsSingleElement)
1243        {
1244            return pTopLevelEntity->pEffect->CreatePooledSingleElementTypeInterface( pType );
1245        }
1246        else
1247        {
1248            return (ID3DX11EffectType*) pType;
1249        }
1250    }
1251
1252    STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) override
1253    {
1254        HRESULT hr = S_OK;
1255        static LPCSTR pFuncName = "ID3DX11EffectVariable::GetDesc";
1256
1257        VERIFYPARAMETER(pDesc != nullptr);
1258
1259        pDesc->Name = pName;
1260        pDesc->Semantic = pSemantic;
1261        pDesc->Flags = 0;
1262
1263        if (pTopLevelEntity->pEffect->IsReflectionData(pTopLevelEntity))
1264        {
1265            // Is part of an annotation
1266            assert(pTopLevelEntity->pEffect->IsReflectionData(Data.pGeneric));
1267            pDesc->Annotations = 0;
1268            pDesc->BufferOffset = 0;
1269            pDesc->Flags |= D3DX11_EFFECT_VARIABLE_ANNOTATION;
1270        }
1271        else
1272        {
1273            // Is part of a global variable
1274            assert(pTopLevelEntity->pEffect->IsRuntimeData(pTopLevelEntity));
1275            if (!pTopLevelEntity->pType->IsObjectType(EOT_String))
1276            {
1277                // strings are funny; their data is reflection data, so ignore those
1278                assert(pTopLevelEntity->pEffect->IsRuntimeData(Data.pGeneric));
1279            }
1280
1281            pDesc->Annotations = ((TGlobalVariable<ID3DX11Effect>*)pTopLevelEntity)->AnnotationCount;
1282
1283            SConstantBuffer *pCB = ((TGlobalVariable<ID3DX11Effect>*)pTopLevelEntity)->pCB;
1284
1285            if (pType->BelongsInConstantBuffer())
1286            {
1287                assert(pCB != 0);
1288                _Analysis_assume_(pCB != 0);
1289                UINT_PTR offset = Data.pNumeric - pCB->pBackingStore;
1290                assert(offset == (uint32_t)offset);
1291                pDesc->BufferOffset = (uint32_t)offset;
1292                assert(pDesc->BufferOffset >= 0 && pDesc->BufferOffset + GetTotalUnpackedSize() <= pCB->Size);
1293            }
1294            else
1295            {
1296                assert(pCB == nullptr);
1297                pDesc->BufferOffset = 0;
1298            }
1299        }
1300
1301lExit:
1302        return hr;
1303    }
1304
1305    TTopLevelVariable<ID3DX11EffectVariable> * GetTopLevelEntity()
1306    {
1307        return pTopLevelEntity;
1308    }
1309
1310    bool IsArray()
1311    {
1312        return (pType->Elements > 0 && !IsSingleElement);
1313    }
1314
1315    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override
1316    { return pTopLevelEntity->GetAnnotationByIndex(Index); }
1317    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override
1318    { return pTopLevelEntity->GetAnnotationByName(Name); }
1319
1320    STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)() override
1321    { return pTopLevelEntity->GetParentConstantBuffer(); }
1322
1323    // Annotations should never be able to go down this codepath
1324    void DirtyVariable()
1325    {
1326        // make sure to call the global variable's version of dirty variable
1327        ((TGlobalVariable<ID3DX11EffectVariable>*)pTopLevelEntity)->DirtyVariable();
1328    }
1329};
1330
1331//////////////////////////////////////////////////////////////////////////
1332// TAnnotation - functionality for top level annotations
1333//////////////////////////////////////////////////////////////////////////
1334
1335template<typename IBaseInterface>
1336struct TAnnotation : public TVariable<TTopLevelVariable<IBaseInterface> >
1337{
1338    STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) override
1339    {
1340        HRESULT hr = S_OK;
1341        static LPCSTR pFuncName = "ID3DX11EffectVariable::GetDesc";
1342
1343        VERIFYPARAMETER(pDesc != nullptr);
1344
1345        pDesc->Name = pName;
1346        pDesc->Semantic = pSemantic;
1347        pDesc->Flags = D3DX11_EFFECT_VARIABLE_ANNOTATION;
1348        pDesc->Annotations = 0;
1349        pDesc->BufferOffset = 0;
1350        pDesc->ExplicitBindPoint = 0;
1351
1352lExit:
1353        return hr;
1354
1355    }
1356
1357    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override
1358    {
1359        UNREFERENCED_PARAMETER(Index);
1360        static LPCSTR pFuncName = "ID3DX11EffectVariable::GetAnnotationByIndex";
1361        DPF(0, "%s: Only variables may have annotations", pFuncName);
1362        return &g_InvalidScalarVariable;
1363    }
1364
1365    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override
1366    {
1367        UNREFERENCED_PARAMETER(Name);
1368        static LPCSTR pFuncName = "ID3DX11EffectVariable::GetAnnotationByName";
1369        DPF(0, "%s: Only variables may have annotations", pFuncName);
1370        return &g_InvalidScalarVariable;
1371    }
1372
1373    STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)() override
1374    { return NoParentCB(); }
1375
1376    void DirtyVariable()
1377    {
1378        assert(0);
1379    }
1380};
1381
1382//////////////////////////////////////////////////////////////////////////
1383// TGlobalVariable - functionality for top level global variables
1384//////////////////////////////////////////////////////////////////////////
1385
1386template<typename IBaseInterface>
1387struct TGlobalVariable : public TVariable<TTopLevelVariable<IBaseInterface> >
1388{
1389    Timer           LastModifiedTime;
1390
1391    // if numeric, pointer to the constant buffer where this variable lives
1392    SConstantBuffer *pCB;
1393
1394    uint32_t        AnnotationCount;
1395    SAnnotation     *pAnnotations;
1396
1397    TGlobalVariable() noexcept :
1398        LastModifiedTime(0),
1399        pCB(nullptr),
1400        AnnotationCount(0),
1401        pAnnotations(nullptr)
1402    {
1403    }
1404
1405    STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc)
1406    {
1407        HRESULT hr = S_OK;
1408        static LPCSTR pFuncName = "ID3DX11EffectVariable::GetDesc";
1409
1410        VERIFYPARAMETER(pDesc != nullptr);
1411
1412        pDesc->Name = pName;
1413        pDesc->Semantic = pSemantic;
1414        pDesc->Flags = 0;
1415        pDesc->Annotations = AnnotationCount;
1416
1417        if (pType->BelongsInConstantBuffer())
1418        {
1419            assert(pCB != 0);
1420            _Analysis_assume_(pCB != 0);
1421            UINT_PTR offset = Data.pNumeric - pCB->pBackingStore;
1422            assert(offset == (uint32_t)offset);
1423            pDesc->BufferOffset = (uint32_t)offset;
1424            assert(pDesc->BufferOffset >= 0 && pDesc->BufferOffset + GetTotalUnpackedSize() <= pCB->Size );
1425        }
1426        else
1427        {
1428            assert(pCB == nullptr);
1429            pDesc->BufferOffset = 0;
1430        }
1431
1432        if (ExplicitBindPoint != -1)
1433        {
1434            pDesc->ExplicitBindPoint = ExplicitBindPoint;
1435            pDesc->Flags |= D3DX11_EFFECT_VARIABLE_EXPLICIT_BIND_POINT;
1436        }
1437        else
1438        {
1439            pDesc->ExplicitBindPoint = 0;
1440        }
1441
1442lExit:
1443        return hr;
1444    }
1445
1446    // these are all well defined for global vars
1447    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index)
1448    {
1449        return GetAnnotationByIndexHelper("ID3DX11EffectVariable", Index, AnnotationCount, pAnnotations);
1450    }
1451
1452    STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name)
1453    {
1454        return GetAnnotationByNameHelper("ID3DX11EffectVariable", Name, AnnotationCount, pAnnotations);
1455    }
1456
1457    STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)()
1458    {
1459        if (nullptr != pCB)
1460        {
1461            assert(pType->BelongsInConstantBuffer());
1462            return (ID3DX11EffectConstantBuffer*)pCB;
1463        }
1464        else
1465        {
1466            assert(!pType->BelongsInConstantBuffer());
1467            return &g_InvalidConstantBuffer;
1468        }
1469    }
1470
1471    inline void DirtyVariable()
1472    {
1473        assert(pCB != 0);
1474        _Analysis_assume_(pCB != 0);
1475        pCB->IsDirty = true;
1476        LastModifiedTime = pEffect->GetCurrentTime();
1477    }
1478
1479};
1480
1481//////////////////////////////////////////////////////////////////////////
1482// TNumericVariable - implements raw set/get functionality
1483//////////////////////////////////////////////////////////////////////////
1484
1485// IMPORTANT NOTE: All of these numeric & object aspect classes MUST NOT
1486// add data members to the base variable classes.  Otherwise type sizes
1487// will disagree between object & numeric variables and we cannot eaily
1488// create arrays of global variables using SGlobalVariable
1489
1490// Requires that IBaseInterface have SVariable's members, GetTotalUnpackedSize() and DirtyVariable()
1491template<typename IBaseInterface, bool IsAnnotation>
1492struct TNumericVariable : public IBaseInterface
1493{
1494    STDMETHOD(SetRawValue)(_In_reads_bytes_(ByteCount) const void *pData, _In_ uint32_t ByteOffset, _In_ uint32_t ByteCount) override
1495    {
1496        if (IsAnnotation)
1497        {
1498            return AnnotationInvalidSetCall("ID3DX11EffectVariable::SetRawValue");
1499        }
1500        else
1501        {
1502            HRESULT hr = S_OK;
1503
1504#ifdef _DEBUG
1505            static LPCSTR pFuncName = "ID3DX11EffectVariable::SetRawValue";
1506
1507            VERIFYPARAMETER(pData);
1508
1509            if ((ByteOffset + ByteCount < ByteOffset) ||
1510                (ByteCount + (uint8_t*)pData < (uint8_t*)pData) ||
1511                ((ByteOffset + ByteCount) > GetTotalUnpackedSize()))
1512            {
1513                // overflow of some kind
1514                DPF(0, "%s: Invalid range specified", pFuncName);
1515                VH(E_INVALIDARG);
1516            }
1517#endif
1518
1519            DirtyVariable();
1520            memcpy(Data.pNumeric + ByteOffset, pData, ByteCount);
1521
1522lExit:
1523            return hr;
1524        }
1525    }
1526
1527    STDMETHOD(GetRawValue)(_Out_writes_bytes_(ByteCount) void *pData, _In_ uint32_t ByteOffset, _In_ uint32_t ByteCount) override
1528    {
1529        HRESULT hr = S_OK;
1530
1531#ifdef _DEBUG
1532        static LPCSTR pFuncName = "ID3DX11EffectVariable::GetRawValue";
1533
1534        VERIFYPARAMETER(pData);
1535
1536        if ((ByteOffset + ByteCount < ByteOffset) ||
1537            (ByteCount + (uint8_t*)pData < (uint8_t*)pData) ||
1538            ((ByteOffset + ByteCount) > GetTotalUnpackedSize()))
1539        {
1540            // overflow of some kind
1541            DPF(0, "%s: Invalid range specified", pFuncName);
1542            VH(E_INVALIDARG);
1543        }
1544#endif
1545
1546        memcpy(pData, Data.pNumeric + ByteOffset, ByteCount);
1547
1548lExit:
1549        return hr;
1550    }
1551};
1552
1553//////////////////////////////////////////////////////////////////////////
1554// ID3DX11EffectScalarVariable (TFloatScalarVariable implementation)
1555//////////////////////////////////////////////////////////////////////////
1556
1557template<typename IBaseInterface, bool IsAnnotation>
1558struct TFloatScalarVariable : public TNumericVariable<IBaseInterface, IsAnnotation>
1559{
1560    STDMETHOD(SetFloat)(_In_ const float Value) override;
1561    STDMETHOD(GetFloat)(_Out_ float *pValue) override;
1562
1563    STDMETHOD(SetFloatArray)(_In_reads_(Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1564    STDMETHOD(GetFloatArray)(_Out_writes_(Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1565
1566    STDMETHOD(SetInt)(_In_ const int Value) override;
1567    STDMETHOD(GetInt)(_Out_ int *pValue) override;
1568
1569    STDMETHOD(SetIntArray)(_In_reads_(Count) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1570    STDMETHOD(GetIntArray)(_Out_writes_(Count) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1571
1572    STDMETHOD(SetBool)(_In_ const bool Value) override;
1573    STDMETHOD(GetBool)(_Out_ bool *pValue) override;
1574
1575    STDMETHOD(SetBoolArray)(_In_reads_(Count) const bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1576    STDMETHOD(GetBoolArray)(_Out_writes_(Count) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1577};
1578
1579template<typename IBaseInterface, bool IsAnnotation>
1580_Use_decl_annotations_
1581HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::SetFloat(float Value)
1582{
1583    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloat";
1584    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1585    DirtyVariable();
1586    return CopyScalarValue<ETVT_Float, ETVT_Float, float, false>(Value, Data.pNumericFloat, pFuncName);
1587}
1588
1589template<typename IBaseInterface, bool IsAnnotation>
1590_Use_decl_annotations_
1591HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetFloat(float *pValue)
1592{
1593    return CopyScalarValue<ETVT_Float, ETVT_Float, float, true>(*Data.pNumericFloat, pValue, "ID3DX11EffectScalarVariable::GetFloat");
1594}
1595
1596template<typename IBaseInterface, bool IsAnnotation>
1597_Use_decl_annotations_
1598HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::SetFloatArray(const float *pData, uint32_t Offset, uint32_t Count)
1599{
1600    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloatArray";
1601    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1602    DirtyVariable();
1603    return SetScalarArray<ETVT_Float, ETVT_Float, float, float>(pData, Data.pNumericFloat, Offset, Count,
1604        pType, GetTotalUnpackedSize(), pFuncName);
1605}
1606
1607template<typename IBaseInterface, bool IsAnnotation>
1608_Use_decl_annotations_
1609HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetFloatArray(float *pData, uint32_t Offset, uint32_t Count)
1610{
1611    return GetScalarArray<ETVT_Float, ETVT_Float, float, float>(Data.pNumericFloat, pData, Offset, Count,
1612        pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetFloatArray");
1613}
1614
1615template<typename IBaseInterface, bool IsAnnotation>
1616_Use_decl_annotations_
1617HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::SetInt(const int Value)
1618{
1619    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetInt";
1620    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1621    DirtyVariable();
1622    return CopyScalarValue<ETVT_Int, ETVT_Float, int, false>(Value, Data.pNumericFloat, pFuncName);
1623}
1624
1625template<typename IBaseInterface, bool IsAnnotation>
1626_Use_decl_annotations_
1627HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetInt(int *pValue)
1628{
1629    return CopyScalarValue<ETVT_Float, ETVT_Int, float, true>(*Data.pNumericFloat, pValue, "ID3DX11EffectScalarVariable::GetInt");
1630}
1631
1632template<typename IBaseInterface, bool IsAnnotation>
1633_Use_decl_annotations_
1634HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::SetIntArray(const int *pData, uint32_t Offset, uint32_t Count)
1635{
1636    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetIntArray";
1637    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1638    DirtyVariable();
1639    return SetScalarArray<ETVT_Int, ETVT_Float, int, float>(pData, Data.pNumericFloat, Offset, Count,
1640        pType, GetTotalUnpackedSize(), pFuncName);
1641}
1642
1643template<typename IBaseInterface, bool IsAnnotation>
1644_Use_decl_annotations_
1645HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetIntArray(int *pData, uint32_t Offset, uint32_t Count)
1646{
1647    return GetScalarArray<ETVT_Float, ETVT_Int, float, int>(Data.pNumericFloat, pData, Offset, Count,
1648        pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetIntArray");
1649}
1650
1651template<typename IBaseInterface, bool IsAnnotation>
1652_Use_decl_annotations_
1653HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::SetBool(const bool Value)
1654{
1655    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetBool";
1656    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1657    DirtyVariable();
1658    return CopyScalarValue<ETVT_bool, ETVT_Float, bool, false>(Value, Data.pNumericFloat, pFuncName);
1659}
1660
1661template<typename IBaseInterface, bool IsAnnotation>
1662_Use_decl_annotations_
1663HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetBool(bool *pValue)
1664{
1665    return CopyScalarValue<ETVT_Float, ETVT_bool, float, true>(*Data.pNumericFloat, pValue, "ID3DX11EffectScalarVariable::GetBool");
1666}
1667
1668template<typename IBaseInterface, bool IsAnnotation>
1669_Use_decl_annotations_
1670HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::SetBoolArray(const bool *pData, uint32_t Offset, uint32_t Count)
1671{
1672    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetBoolArray";
1673    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1674    DirtyVariable();
1675    return SetScalarArray<ETVT_bool, ETVT_Float, bool, float>(pData, Data.pNumericFloat, Offset, Count,
1676        pType, GetTotalUnpackedSize(), pFuncName);
1677}
1678
1679template<typename IBaseInterface, bool IsAnnotation>
1680_Use_decl_annotations_
1681HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetBoolArray(bool *pData, uint32_t Offset, uint32_t Count)
1682{
1683    return GetScalarArray<ETVT_Float, ETVT_bool, float, bool>(Data.pNumericFloat, pData, Offset, Count,
1684        pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetBoolArray");
1685}
1686
1687//////////////////////////////////////////////////////////////////////////
1688// ID3DX11EffectScalarVariable (TIntScalarVariable implementation)
1689//////////////////////////////////////////////////////////////////////////
1690
1691template<typename IBaseInterface, bool IsAnnotation>
1692struct TIntScalarVariable : public TNumericVariable<IBaseInterface, IsAnnotation>
1693{
1694    STDMETHOD(SetFloat)(_In_ const float Value) override;
1695    STDMETHOD(GetFloat)(_Out_ float *pValue) override;
1696
1697    STDMETHOD(SetFloatArray)(_In_reads_(Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1698    STDMETHOD(GetFloatArray)(_Out_writes_(Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1699
1700    STDMETHOD(SetInt)(_In_ const int Value) override;
1701    STDMETHOD(GetInt)(_Out_ int *pValue) override;
1702
1703    STDMETHOD(SetIntArray)(_In_reads_(Count) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1704    STDMETHOD(GetIntArray)(_Out_writes_(Count) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1705
1706    STDMETHOD(SetBool)(_In_ const bool Value) override;
1707    STDMETHOD(GetBool)(_Out_ bool *pValue) override;
1708
1709    STDMETHOD(SetBoolArray)(_In_reads_(Count) const bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1710    STDMETHOD(GetBoolArray)(_Out_writes_(Count) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1711};
1712
1713template<typename IBaseInterface, bool IsAnnotation>
1714_Use_decl_annotations_
1715HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetFloat(float Value)
1716{
1717    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloat";
1718    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1719    DirtyVariable();
1720    return CopyScalarValue<ETVT_Float, ETVT_Int, float, false>(Value, Data.pNumericInt, pFuncName);
1721}
1722
1723template<typename IBaseInterface, bool IsAnnotation>
1724_Use_decl_annotations_
1725HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetFloat(float *pValue)
1726{
1727    return CopyScalarValue<ETVT_Int, ETVT_Float, int, true>(*Data.pNumericInt, pValue, "ID3DX11EffectScalarVariable::GetFloat");
1728}
1729
1730template<typename IBaseInterface, bool IsAnnotation>
1731_Use_decl_annotations_
1732HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetFloatArray(const float *pData, uint32_t Offset, uint32_t Count)
1733{
1734    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloatArray";
1735    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1736    DirtyVariable();
1737    return SetScalarArray<ETVT_Float, ETVT_Int, float, int>(pData, Data.pNumericInt, Offset, Count,
1738        pType, GetTotalUnpackedSize(), pFuncName);
1739}
1740
1741template<typename IBaseInterface, bool IsAnnotation>
1742_Use_decl_annotations_
1743HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetFloatArray(float *pData, uint32_t Offset, uint32_t Count)
1744{
1745    return GetScalarArray<ETVT_Int, ETVT_Float, int, float>(Data.pNumericInt, pData, Offset, Count,
1746        pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetFloatArray");
1747}
1748
1749template<typename IBaseInterface, bool IsAnnotation>
1750_Use_decl_annotations_
1751HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetInt(const int Value)
1752{
1753    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetInt";
1754    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1755    DirtyVariable();
1756    return CopyScalarValue<ETVT_Int, ETVT_Int, int, false>(Value, Data.pNumericInt, pFuncName);
1757}
1758
1759template<typename IBaseInterface, bool IsAnnotation>
1760_Use_decl_annotations_
1761HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetInt(int *pValue)
1762{
1763    return CopyScalarValue<ETVT_Int, ETVT_Int, int, true>(*Data.pNumericInt, pValue, "ID3DX11EffectScalarVariable::GetInt");
1764}
1765
1766template<typename IBaseInterface, bool IsAnnotation>
1767_Use_decl_annotations_
1768HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetIntArray(const int *pData, uint32_t Offset, uint32_t Count)
1769{
1770    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetIntArray";
1771    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1772    DirtyVariable();
1773    return SetScalarArray<ETVT_Int, ETVT_Int, int, int>(pData, Data.pNumericInt, Offset, Count,
1774        pType, GetTotalUnpackedSize(), pFuncName);
1775}
1776
1777template<typename IBaseInterface, bool IsAnnotation>
1778_Use_decl_annotations_
1779HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetIntArray(int *pData, uint32_t Offset, uint32_t Count)
1780{
1781    return GetScalarArray<ETVT_Int, ETVT_Int, int, int>(Data.pNumericInt, pData, Offset, Count,
1782        pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetIntArray");
1783}
1784
1785template<typename IBaseInterface, bool IsAnnotation>
1786_Use_decl_annotations_
1787HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetBool(const bool Value)
1788{
1789    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetBool";
1790    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1791    DirtyVariable();
1792    return CopyScalarValue<ETVT_bool, ETVT_Int, bool, false>(Value, Data.pNumericInt, pFuncName);
1793}
1794
1795template<typename IBaseInterface, bool IsAnnotation>
1796_Use_decl_annotations_
1797HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetBool(bool *pValue)
1798{
1799    return CopyScalarValue<ETVT_Int, ETVT_bool, int, true>(*Data.pNumericInt, pValue, "ID3DX11EffectScalarVariable::GetBool");
1800}
1801
1802template<typename IBaseInterface, bool IsAnnotation>
1803_Use_decl_annotations_
1804HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetBoolArray(const bool *pData, uint32_t Offset, uint32_t Count)
1805{
1806    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetBoolArray";
1807    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1808    DirtyVariable();
1809    return SetScalarArray<ETVT_bool, ETVT_Int, bool, int>(pData, Data.pNumericInt, Offset, Count,
1810        pType, GetTotalUnpackedSize(), pFuncName);
1811}
1812
1813template<typename IBaseInterface, bool IsAnnotation>
1814_Use_decl_annotations_
1815HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetBoolArray(bool *pData, uint32_t Offset, uint32_t Count)
1816{
1817    return GetScalarArray<ETVT_Int, ETVT_bool, int, bool>(Data.pNumericInt, pData, Offset, Count,
1818        pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetBoolArray");
1819}
1820
1821//////////////////////////////////////////////////////////////////////////
1822// ID3DX11EffectScalarVariable (TBoolScalarVariable implementation)
1823//////////////////////////////////////////////////////////////////////////
1824
1825template<typename IBaseInterface, bool IsAnnotation>
1826struct TBoolScalarVariable : public TNumericVariable<IBaseInterface, IsAnnotation>
1827{
1828    STDMETHOD(SetFloat)(_In_ const float Value) override;
1829    STDMETHOD(GetFloat)(_Out_ float *pValue) override;
1830
1831    STDMETHOD(SetFloatArray)(_In_reads_(Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1832    STDMETHOD(GetFloatArray)(_Out_writes_(Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1833
1834    STDMETHOD(SetInt)(_In_ const int Value) override;
1835    STDMETHOD(GetInt)(_Out_ int *pValue) override;
1836
1837    STDMETHOD(SetIntArray)(_In_reads_(Count) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1838    STDMETHOD(GetIntArray)(_Out_writes_(Count) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1839
1840    STDMETHOD(SetBool)(_In_ const bool Value) override;
1841    STDMETHOD(GetBool)(_Out_ bool *pValue) override;
1842
1843    STDMETHOD(SetBoolArray)(_In_reads_(Count) const bool *pData, uint32_t Offset, _In_ uint32_t Count) override;
1844    STDMETHOD(GetBoolArray)(_Out_writes_(Count) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1845};
1846
1847template<typename IBaseInterface, bool IsAnnotation>
1848_Use_decl_annotations_
1849HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::SetFloat(float Value)
1850{
1851    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloat";
1852    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1853    DirtyVariable();
1854    return CopyScalarValue<ETVT_Float, ETVT_Bool, float, false>(Value, Data.pNumericBool, pFuncName);
1855}
1856
1857template<typename IBaseInterface, bool IsAnnotation>
1858_Use_decl_annotations_
1859HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetFloat(float *pValue)
1860{
1861    return CopyScalarValue<ETVT_Bool, ETVT_Float, BOOL, true>(*Data.pNumericBool, pValue, "ID3DX11EffectScalarVariable::GetFloat");
1862}
1863
1864template<typename IBaseInterface, bool IsAnnotation>
1865_Use_decl_annotations_
1866HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::SetFloatArray(const float *pData, uint32_t Offset, uint32_t Count)
1867{
1868    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloatArray";
1869    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1870    DirtyVariable();
1871    return SetScalarArray<ETVT_Float, ETVT_Bool, float, BOOL>(pData, Data.pNumericBool, Offset, Count,
1872        pType, GetTotalUnpackedSize(), pFuncName);
1873}
1874
1875template<typename IBaseInterface, bool IsAnnotation>
1876_Use_decl_annotations_
1877HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetFloatArray(float *pData, uint32_t Offset, uint32_t Count)
1878{
1879    return GetScalarArray<ETVT_Bool, ETVT_Float, BOOL, float>(Data.pNumericBool, pData, Offset, Count,
1880        pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetFloatArray");
1881}
1882
1883template<typename IBaseInterface, bool IsAnnotation>
1884_Use_decl_annotations_
1885HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::SetInt(const int Value)
1886{
1887    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetInt";
1888    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1889    DirtyVariable();
1890    return CopyScalarValue<ETVT_Int, ETVT_Bool, int, false>(Value, Data.pNumericBool, pFuncName);
1891}
1892
1893template<typename IBaseInterface, bool IsAnnotation>
1894_Use_decl_annotations_
1895HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetInt(int *pValue)
1896{
1897    return CopyScalarValue<ETVT_Bool, ETVT_Int, BOOL, true>(*Data.pNumericBool, pValue, "ID3DX11EffectScalarVariable::GetInt");
1898}
1899
1900template<typename IBaseInterface, bool IsAnnotation>
1901_Use_decl_annotations_
1902HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::SetIntArray(const int *pData, uint32_t Offset, uint32_t Count)
1903{
1904    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetIntArray";
1905    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1906    DirtyVariable();
1907    return SetScalarArray<ETVT_Int, ETVT_Bool, int, BOOL>(pData, Data.pNumericBool, Offset, Count,
1908        pType, GetTotalUnpackedSize(), pFuncName);
1909}
1910
1911template<typename IBaseInterface, bool IsAnnotation>
1912_Use_decl_annotations_
1913HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetIntArray(int *pData, uint32_t Offset, uint32_t Count)
1914{
1915    return GetScalarArray<ETVT_Bool, ETVT_Int, BOOL, int>(Data.pNumericBool, pData, Offset, Count,
1916        pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetIntArray");
1917}
1918
1919template<typename IBaseInterface, bool IsAnnotation>
1920_Use_decl_annotations_
1921HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::SetBool(const bool Value)
1922{
1923    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetBool";
1924    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1925    DirtyVariable();
1926    return CopyScalarValue<ETVT_bool, ETVT_Bool, bool, false>(Value, Data.pNumericBool, pFuncName);
1927}
1928
1929template<typename IBaseInterface, bool IsAnnotation>
1930_Use_decl_annotations_
1931HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetBool(bool *pValue)
1932{
1933    return CopyScalarValue<ETVT_Bool, ETVT_bool, BOOL, true>(*Data.pNumericBool, pValue, "ID3DX11EffectScalarVariable::GetBool");
1934}
1935
1936template<typename IBaseInterface, bool IsAnnotation>
1937_Use_decl_annotations_
1938HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::SetBoolArray(const bool *pData, uint32_t Offset, uint32_t Count)
1939{
1940    static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetBoolArray";
1941    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
1942    DirtyVariable();
1943    return SetScalarArray<ETVT_bool, ETVT_Bool, bool, BOOL>(pData, Data.pNumericBool, Offset, Count,
1944        pType, GetTotalUnpackedSize(), pFuncName);
1945}
1946
1947template<typename IBaseInterface, bool IsAnnotation>
1948_Use_decl_annotations_
1949HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetBoolArray(bool *pData, uint32_t Offset, uint32_t Count)
1950{
1951    return GetScalarArray<ETVT_Bool, ETVT_bool, BOOL, bool>(Data.pNumericBool, pData, Offset, Count,
1952        pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetBoolArray");
1953}
1954
1955//////////////////////////////////////////////////////////////////////////
1956// ID3DX11EffectVectorVariable (TVectorVariable implementation)
1957//////////////////////////////////////////////////////////////////////////
1958
1959template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType >
1960struct TVectorVariable : public TNumericVariable<IBaseInterface, IsAnnotation>
1961{
1962    STDMETHOD(SetBoolVector) (_In_reads_(4) const bool *pData) override;
1963    STDMETHOD(SetIntVector)  (_In_reads_(4) const int *pData) override;
1964    STDMETHOD(SetFloatVector)(_In_reads_(4) const float *pData) override;
1965
1966    STDMETHOD(GetBoolVector) (_Out_writes_(4) bool *pData) override;
1967    STDMETHOD(GetIntVector)  (_Out_writes_(4) int *pData) override;
1968    STDMETHOD(GetFloatVector)(_Out_writes_(4) float *pData) override;
1969
1970
1971    STDMETHOD(SetBoolVectorArray) (_In_reads_(Count*4) const bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1972    STDMETHOD(SetIntVectorArray)  (_In_reads_(Count*4) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1973    STDMETHOD(SetFloatVectorArray)(_In_reads_(Count*4) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1974
1975    STDMETHOD(GetBoolVectorArray) (_Out_writes_(Count*4) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1976    STDMETHOD(GetIntVectorArray)  (_Out_writes_(Count*4) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1977    STDMETHOD(GetFloatVectorArray)(_Out_writes_(Count*4) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
1978};
1979
1980// Note that branches in this code is based on template parameters and will be compiled out
1981#pragma warning (push)
1982#pragma warning (disable : 6101)
1983template <ETemplateVarType DestType, ETemplateVarType SourceType>
1984void __forceinline CopyDataWithTypeConversion(_Out_ void *pDest,
1985                                              _In_ const void *pSource,
1986                                              _In_ size_t dstVecSize, _In_ size_t srcVecSize,
1987                                              _In_ size_t elementCount, _In_ size_t vecCount)
1988{
1989    switch (SourceType)
1990    {
1991    case ETVT_Bool:
1992        switch (DestType)
1993        {
1994        case ETVT_Bool:
1995            for (size_t j=0; j<vecCount; j++)
1996            {
1997                memcpy(pDest, pSource, elementCount * SType::c_ScalarSize);
1998
1999                pDest = ((float*) pDest) + dstVecSize;
2000                pSource = ((float*) pSource) + srcVecSize;
2001            }
2002            break;
2003
2004        case ETVT_Int:
2005            for (size_t j=0; j<vecCount; j++)
2006            {
2007                for (size_t i=0; i<elementCount; i++)
2008                    ((int*)pDest)[i] = ((bool*)pSource)[i] ? -1 : 0;
2009
2010                pDest = ((float*) pDest) + dstVecSize;
2011                pSource = ((float*) pSource) + srcVecSize;
2012            }
2013            break;
2014
2015        case ETVT_Float:
2016            for (size_t j=0; j<vecCount; j++)
2017            {
2018                for (size_t i=0; i<elementCount; i++)
2019                    ((float*)pDest)[i] = ((bool*)pSource)[i] ? -1.0f : 0.0f;
2020
2021                pDest = ((float*) pDest) + dstVecSize;
2022                pSource = ((float*) pSource) + srcVecSize;
2023            }
2024            break;
2025
2026        case ETVT_bool:
2027            for (size_t j=0; j<vecCount; j++)
2028            {
2029                for (size_t i=0; i<elementCount; i++)
2030                    ((bool*)pDest)[i] = (((int*)pSource)[i] != 0) ? true : false;
2031
2032                pDest = ((bool*) pDest) + dstVecSize;
2033                pSource = ((float*) pSource) + srcVecSize;
2034            }
2035            break;
2036
2037        default:
2038            assert(0);
2039        }
2040        break;
2041
2042    case ETVT_Int:
2043        switch (DestType)
2044        {
2045        case ETVT_Bool:
2046            for (size_t j=0; j<vecCount; j++)
2047            {
2048                for (size_t i=0; i<elementCount; i++)
2049                    ((int*)pDest)[i] = (((int*)pSource)[i] != 0) ? -1 : 0;
2050
2051                pDest = ((float*) pDest) + dstVecSize;
2052                pSource = ((float*) pSource) + srcVecSize;
2053            }
2054            break;
2055
2056        case ETVT_Int:
2057            for (size_t j=0; j<vecCount; j++)
2058            {
2059                memcpy(pDest, pSource, elementCount * SType::c_ScalarSize);
2060
2061                pDest = ((float*) pDest) + dstVecSize;
2062                pSource = ((float*) pSource) + srcVecSize;
2063            }
2064            break;
2065
2066        case ETVT_Float:
2067            for (size_t j=0; j<vecCount; j++)
2068            {
2069                for (size_t i=0; i<elementCount; i++)
2070                    ((float*)pDest)[i] = (float)(((int*)pSource)[i]);
2071
2072                pDest = ((float*) pDest) + dstVecSize;
2073                pSource = ((float*) pSource) + srcVecSize;
2074            }
2075            break;
2076
2077        case ETVT_bool:
2078            for (size_t j=0; j<vecCount; j++)
2079            {
2080                for (size_t i=0; i<elementCount; i++)
2081                    ((bool*)pDest)[i] = (((int*)pSource)[i] != 0) ? true : false;
2082
2083                pDest = ((bool*) pDest) + dstVecSize;
2084                pSource = ((float*) pSource) + srcVecSize;
2085            }
2086            break;
2087
2088        default:
2089            assert(0);
2090        }
2091        break;
2092
2093    case ETVT_Float:
2094        switch (DestType)
2095        {
2096        case ETVT_Bool:
2097            for (size_t j=0; j<vecCount; j++)
2098            {
2099                for (size_t i=0; i<elementCount; i++)
2100                    ((int*)pDest)[i] = (((float*)pSource)[i] != 0.0f) ? -1 : 0;
2101
2102                pDest = ((float*) pDest) + dstVecSize;
2103                pSource = ((float*) pSource) + srcVecSize;
2104            }
2105            break;
2106
2107        case ETVT_Int:
2108            for (size_t j=0; j<vecCount; j++)
2109            {
2110                for (size_t i=0; i<elementCount; i++)
2111                    ((int*)pDest)[i] = (int)((float*)pSource)[i];
2112
2113                pDest = ((float*) pDest) + dstVecSize;
2114                pSource = ((float*) pSource) + srcVecSize;
2115            }
2116            break;
2117
2118        case ETVT_Float:
2119            for (size_t i=0; i<vecCount; i++)
2120            {
2121                memcpy( pDest, pSource, elementCount * SType::c_ScalarSize);
2122
2123                pDest = ((float*) pDest) + dstVecSize;
2124                pSource = ((float*) pSource) + srcVecSize;
2125            }
2126            break;
2127
2128        case ETVT_bool:
2129            for (size_t j=0; j<vecCount; j++)
2130            {
2131                for (size_t i=0; i<elementCount; i++)
2132                    ((bool*)pDest)[i] = (((float*)pSource)[i] != 0.0f) ? true : false;
2133
2134                pDest = ((bool*) pDest) + dstVecSize;
2135                pSource = ((float*) pSource) + srcVecSize;
2136            }
2137            break;
2138
2139        default:
2140            assert(0);
2141        }
2142        break;
2143
2144    case ETVT_bool:
2145        switch (DestType)
2146        {
2147        case ETVT_Bool:
2148            for (size_t j=0; j<vecCount; j++)
2149            {
2150                for (size_t i=0; i<elementCount; i++)
2151                    reinterpret_cast<int*>(pDest)[i] = reinterpret_cast<const bool*>(pSource)[i] ? -1 : 0;
2152
2153                pDest = ((float*) pDest) + dstVecSize;
2154                pSource = ((bool*) pSource) + srcVecSize;
2155            }
2156            break;
2157
2158        case ETVT_Int:
2159            for (size_t j=0; j<vecCount; j++)
2160            {
2161                for (size_t i=0; i<elementCount; i++)
2162                    reinterpret_cast<int*>(pDest)[i] = reinterpret_cast<const bool*>(pSource)[i] ? -1 : 0;
2163
2164                pDest = ((float*) pDest) + dstVecSize;
2165                pSource = ((bool*) pSource) + srcVecSize;
2166            }
2167            break;
2168
2169        case ETVT_Float:
2170            for (size_t j=0; j<vecCount; j++)
2171            {
2172                for (size_t i=0; i<elementCount; i++)
2173                    reinterpret_cast<float*>(pDest)[i] = reinterpret_cast<const bool*>(pSource)[i] ? -1.0f : 0.0f;
2174
2175                pDest = ((float*) pDest) + dstVecSize;
2176                pSource = ((bool*) pSource) + srcVecSize;
2177            }
2178            break;
2179
2180        case ETVT_bool:
2181            for (size_t j=0; j<vecCount; j++)
2182            {
2183                memcpy(pDest, pSource, elementCount);
2184
2185                pDest = ((bool*) pDest) + dstVecSize;
2186                pSource = ((bool*) pSource) + srcVecSize;
2187            }
2188            break;
2189
2190        default:
2191            assert(0);
2192        }
2193        break;
2194
2195    default:
2196        assert(0);
2197    }
2198}
2199#pragma warning (pop)
2200
2201// Float Vector
2202
2203template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
2204_Use_decl_annotations_
2205HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType >::SetFloatVector(const float *pData)
2206{
2207    HRESULT hr = S_OK;
2208    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetFloatVector";
2209
2210#ifdef _DEBUG
2211    VERIFYPARAMETER(pData);
2212#endif
2213
2214    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
2215    DirtyVariable();
2216    CopyDataWithTypeConversion<BaseType, ETVT_Float>(Data.pVector, pData, 4, pType->NumericType.Columns, pType->NumericType.Columns, 1);
2217
2218lExit:
2219    return hr;
2220}
2221
2222template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
2223_Use_decl_annotations_
2224HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetFloatVector(float *pData)
2225{
2226    HRESULT hr = S_OK;
2227    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetFloatVector";
2228
2229#ifdef _DEBUG
2230    VERIFYPARAMETER(pData);
2231#endif
2232
2233    CopyDataWithTypeConversion<ETVT_Float, BaseType>(pData, Data.pVector, pType->NumericType.Columns, 4, pType->NumericType.Columns, 1);
2234
2235lExit:
2236    return hr;
2237}
2238
2239// Int Vector
2240
2241template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
2242_Use_decl_annotations_
2243HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType >::SetIntVector(const int *pData)
2244{
2245    HRESULT hr = S_OK;
2246    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetIntVector";
2247
2248#ifdef _DEBUG
2249    VERIFYPARAMETER(pData);
2250#endif
2251
2252    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
2253    DirtyVariable();
2254    CopyDataWithTypeConversion<BaseType, ETVT_Int>(Data.pVector, pData, 4, pType->NumericType.Columns, pType->NumericType.Columns, 1);
2255
2256lExit:
2257    return hr;
2258}
2259
2260template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
2261_Use_decl_annotations_
2262HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetIntVector(int *pData)
2263{
2264    HRESULT hr = S_OK;
2265
2266#ifdef _DEBUG
2267    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetIntVector";
2268    VERIFYPARAMETER(pData);
2269#endif
2270
2271    CopyDataWithTypeConversion<ETVT_Int, BaseType>(pData, Data.pVector, pType->NumericType.Columns, 4, pType->NumericType.Columns, 1);
2272
2273lExit:
2274    return hr;
2275}
2276
2277// Bool Vector
2278
2279template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
2280_Use_decl_annotations_
2281HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType >::SetBoolVector(const bool *pData)
2282{
2283    HRESULT hr = S_OK;
2284
2285    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetBoolVector";
2286
2287#ifdef _DEBUG
2288    VERIFYPARAMETER(pData);
2289#endif
2290
2291    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
2292    DirtyVariable();
2293    CopyDataWithTypeConversion<BaseType, ETVT_bool>(Data.pVector, pData, 4, pType->NumericType.Columns, pType->NumericType.Columns, 1);
2294
2295lExit:
2296    return hr;
2297}
2298
2299template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
2300_Use_decl_annotations_
2301HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetBoolVector(bool *pData)
2302{
2303    HRESULT hr = S_OK;
2304
2305#ifdef _DEBUG
2306    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetBoolVector";
2307    VERIFYPARAMETER(pData);
2308#endif
2309
2310    CopyDataWithTypeConversion<ETVT_bool, BaseType>(pData, Data.pVector, pType->NumericType.Columns, 4, pType->NumericType.Columns, 1);
2311
2312lExit:
2313    return hr;
2314}
2315
2316// Vector Arrays /////////////////////////////////////////////////////////
2317
2318template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
2319_Use_decl_annotations_
2320HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::SetFloatVectorArray(const float *pData, uint32_t Offset, uint32_t Count)
2321{
2322    HRESULT hr = S_OK;
2323    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetFloatVectorArray";
2324
2325#ifdef _DEBUG
2326#pragma warning( suppress : 6001 )
2327    if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
2328    {
2329        DPF(0, "%s: Invalid range specified", pFuncName);
2330        VH(E_INVALIDARG);
2331    }
2332#endif
2333
2334    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
2335    DirtyVariable();
2336    // ensure we don't write over the padding at the end of the vector array
2337    CopyDataWithTypeConversion<BaseType, ETVT_Float>(Data.pVector + Offset, pData, 4, pType->NumericType.Columns, pType->NumericType.Columns, std::max(std::min((int)Count, (int)pType->Elements - (int)Offset), 0));
2338
2339lExit:
2340    return hr;
2341}
2342
2343template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
2344_Use_decl_annotations_
2345HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetFloatVectorArray(float *pData, uint32_t Offset, uint32_t Count)
2346{
2347    HRESULT hr = S_OK;
2348
2349#ifdef _DEBUG
2350    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetFloatVectorArray";
2351#pragma warning( suppress : 6001 )
2352    if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
2353    {
2354        DPF(0, "%s: Invalid range specified", pFuncName);
2355        VH(E_INVALIDARG);
2356    }
2357#endif
2358
2359    // ensure we don't read past the end of the vector array
2360    CopyDataWithTypeConversion<ETVT_Float, BaseType>(pData, Data.pVector + Offset, pType->NumericType.Columns, 4, pType->NumericType.Columns, std::max(std::min((int)Count, (int)pType->Elements - (int)Offset), 0));
2361
2362lExit:
2363    return hr;
2364}
2365
2366// int
2367
2368template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
2369_Use_decl_annotations_
2370HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::SetIntVectorArray(const int *pData, uint32_t Offset, uint32_t Count)
2371{
2372    HRESULT hr = S_OK;
2373    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetIntVectorArray";
2374
2375#ifdef _DEBUG
2376#pragma warning( suppress : 6001 )
2377    if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
2378    {
2379        DPF(0, "%s: Invalid range specified", pFuncName);
2380        VH(E_INVALIDARG);
2381    }
2382#endif
2383
2384    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
2385    DirtyVariable();
2386    // ensure we don't write over the padding at the end of the vector array
2387    CopyDataWithTypeConversion<BaseType, ETVT_Int>(Data.pVector + Offset, pData, 4, pType->NumericType.Columns, pType->NumericType.Columns, std::max(std::min((int)Count, (int)pType->Elements - (int)Offset), 0));
2388
2389lExit:
2390    return hr;
2391}
2392
2393template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
2394_Use_decl_annotations_
2395HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetIntVectorArray(int *pData, uint32_t Offset, uint32_t Count)
2396{
2397    HRESULT hr = S_OK;
2398    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetIntVectorArray";
2399
2400#ifdef _DEBUG
2401#pragma warning( suppress : 6001 )
2402    if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
2403    {
2404        DPF(0, "%s: Invalid range specified", pFuncName);
2405        VH(E_INVALIDARG);
2406    }
2407#endif
2408
2409    // ensure we don't read past the end of the vector array
2410    CopyDataWithTypeConversion<ETVT_Int, BaseType>(pData, Data.pVector + Offset, pType->NumericType.Columns, 4, pType->NumericType.Columns, std::max(std::min((int)Count, (int)pType->Elements - (int)Offset), 0));
2411
2412lExit:
2413    return hr;
2414}
2415
2416// bool
2417
2418template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
2419_Use_decl_annotations_
2420HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::SetBoolVectorArray(const bool *pData, uint32_t Offset, uint32_t Count)
2421{
2422    HRESULT hr = S_OK;
2423    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetBoolVectorArray";
2424
2425#ifdef _DEBUG
2426#pragma warning( suppress : 6001 )
2427    if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
2428    {
2429        DPF(0, "%s: Invalid range specified", pFuncName);
2430        VH(E_INVALIDARG);
2431    }
2432#endif
2433
2434    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
2435    DirtyVariable();
2436    // ensure we don't write over the padding at the end of the vector array
2437    CopyDataWithTypeConversion<BaseType, ETVT_bool>(Data.pVector + Offset, pData, 4, pType->NumericType.Columns, pType->NumericType.Columns, std::max(std::min((int)Count, (int)pType->Elements - (int)Offset), 0));
2438
2439lExit:
2440    return hr;
2441}
2442
2443template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
2444_Use_decl_annotations_
2445HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetBoolVectorArray(bool *pData, uint32_t Offset, uint32_t Count)
2446{
2447    HRESULT hr = S_OK;
2448    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetBoolVectorArray";
2449
2450#ifdef _DEBUG
2451#pragma warning( suppress : 6001 )
2452    if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
2453    {
2454        DPF(0, "%s: Invalid range specified", pFuncName);
2455        VH(E_INVALIDARG);
2456    }
2457#endif
2458
2459    // ensure we don't read past the end of the vector array
2460    CopyDataWithTypeConversion<ETVT_bool, BaseType>(pData, Data.pVector + Offset, pType->NumericType.Columns, 4, pType->NumericType.Columns, std::max(std::min((int)Count, (int)pType->Elements - (int)Offset), 0));
2461
2462lExit:
2463    return hr;
2464}
2465
2466//////////////////////////////////////////////////////////////////////////
2467// ID3DX11EffectVector4Variable (TVectorVariable implementation) [OPTIMIZED]
2468//////////////////////////////////////////////////////////////////////////
2469
2470template<typename IBaseInterface>
2471struct TVector4Variable : public TVectorVariable<IBaseInterface, false, ETVT_Float>
2472{
2473    STDMETHOD(SetFloatVector)(_In_reads_(4) const float *pData) override;
2474    STDMETHOD(GetFloatVector)(_Out_writes_(4) float *pData) override;
2475
2476    STDMETHOD(SetFloatVectorArray)(_In_reads_(Count*4) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
2477    STDMETHOD(GetFloatVectorArray)(_Out_writes_(Count*4) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
2478};
2479
2480template<typename IBaseInterface>
2481_Use_decl_annotations_
2482HRESULT TVector4Variable<IBaseInterface>::SetFloatVector(const float *pData)
2483{
2484    HRESULT hr = S_OK;
2485    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetFloatVector";
2486
2487#ifdef _DEBUG
2488    VERIFYPARAMETER(pData);
2489#endif
2490
2491    DirtyVariable();
2492    Data.pVector[0] = ((CEffectVector4*) pData)[0];
2493
2494lExit:
2495    return hr;
2496}
2497
2498template<typename IBaseInterface>
2499_Use_decl_annotations_
2500HRESULT TVector4Variable<IBaseInterface>::GetFloatVector(float *pData)
2501{
2502    HRESULT hr = S_OK;
2503    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetFloatVector";
2504
2505#ifdef _DEBUG
2506    VERIFYPARAMETER(pData);
2507#endif
2508
2509    memcpy(pData, Data.pVector, pType->NumericType.Columns * SType::c_ScalarSize);
2510
2511lExit:
2512    return hr;
2513}
2514
2515template<typename IBaseInterface>
2516_Use_decl_annotations_
2517HRESULT TVector4Variable<IBaseInterface>::SetFloatVectorArray(const float *pData, uint32_t Offset, uint32_t Count)
2518{
2519    HRESULT hr = S_OK;
2520    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetFloatVectorArray";
2521
2522#ifdef _DEBUG
2523#pragma warning( suppress : 6001 )
2524    if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
2525    {
2526        DPF(0, "%s: Invalid range specified", pFuncName);
2527        VH(E_INVALIDARG);
2528    }
2529#endif
2530
2531    DirtyVariable();
2532    // ensure we don't write over the padding at the end of the vector array
2533    memcpy(Data.pVector + Offset, pData,
2534           std::min<size_t>(Count * sizeof(CEffectVector4), pType->TotalSize - (Offset * sizeof(CEffectVector4))));
2535
2536lExit:
2537    return hr;
2538}
2539
2540template<typename IBaseInterface>
2541_Use_decl_annotations_
2542HRESULT TVector4Variable<IBaseInterface>::GetFloatVectorArray(float *pData, uint32_t Offset, uint32_t Count)
2543{
2544    HRESULT hr = S_OK;
2545    static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetFloatVectorArray";
2546
2547#ifdef _DEBUG
2548#pragma warning( suppress : 6001 )
2549    if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
2550    {
2551        DPF(0, "%s: Invalid range specified", pFuncName);
2552        VH(E_INVALIDARG);
2553    }
2554#endif
2555
2556    // ensure we don't read past the end of the vector array
2557    memcpy(pData, Data.pVector + Offset,
2558           std::min<size_t>(Count * sizeof(CEffectVector4), pType->TotalSize - (Offset * sizeof(CEffectVector4))));
2559
2560lExit:
2561    return hr;
2562}
2563
2564
2565//////////////////////////////////////////////////////////////////////////
2566// ID3DX11EffectMatrixVariable (TMatrixVariable implementation)
2567//////////////////////////////////////////////////////////////////////////
2568
2569template<typename IBaseInterface, bool IsAnnotation>
2570struct TMatrixVariable : public TNumericVariable<IBaseInterface, IsAnnotation>
2571{
2572    STDMETHOD(SetMatrix)(_In_reads_(16) const float *pData) override;
2573    STDMETHOD(GetMatrix)(_Out_writes_(16) float *pData) override;
2574
2575    STDMETHOD(SetMatrixArray)(_In_reads_(Count*16) const float *pData, uint32_t Offset, uint32_t Count) override;
2576    STDMETHOD(GetMatrixArray)(_Out_writes_(Count*16) float *pData, uint32_t Offset, uint32_t Count) override;
2577
2578    STDMETHOD(SetMatrixPointerArray)(_In_reads_(Count*16) const float **ppData, uint32_t Offset, uint32_t Count) override;
2579    STDMETHOD(GetMatrixPointerArray)(_Out_writes_(Count*16) float **ppData, uint32_t Offset, uint32_t Count) override;
2580
2581    STDMETHOD(SetMatrixTranspose)(_In_reads_(16) const float *pData) override;
2582    STDMETHOD(GetMatrixTranspose)(_Out_writes_(16) float *pData) override;
2583
2584    STDMETHOD(SetMatrixTransposeArray)(_In_reads_(Count*16) const float *pData, uint32_t Offset, uint32_t Count) override;
2585    STDMETHOD(GetMatrixTransposeArray)(_Out_writes_(Count*16) float *pData, uint32_t Offset, uint32_t Count) override;
2586
2587    STDMETHOD(SetMatrixTransposePointerArray)(_In_reads_(Count*16) const float **ppData, uint32_t Offset, uint32_t Count) override;
2588    STDMETHOD(GetMatrixTransposePointerArray)(_Out_writes_(Count*16) float **ppData, uint32_t Offset, uint32_t Count) override;
2589};
2590
2591#pragma warning (push)
2592#pragma warning (disable : 6101)
2593template<bool Transpose>
2594static void SetMatrixTransposeHelper(_In_ const SType *pType, _Out_writes_bytes_(64) uint8_t *pDestData, _In_reads_(16) const float* pMatrix)
2595{
2596    uint32_t registers, entries;
2597
2598    if (Transpose)
2599    {
2600        // row major
2601        registers = pType->NumericType.Rows;
2602        entries = pType->NumericType.Columns;
2603    }
2604    else
2605    {
2606        // column major
2607        registers = pType->NumericType.Columns;
2608        entries = pType->NumericType.Rows;
2609    }
2610    _Analysis_assume_( registers <= 4 );
2611    _Analysis_assume_( entries <= 4 );
2612
2613    for (size_t i = 0; i < registers; ++ i)
2614    {
2615        for (size_t j = 0; j < entries; ++ j)
2616        {
2617#pragma prefast(suppress:__WARNING_UNRELATED_LOOP_TERMINATION, "regs / entries <= 4")
2618            ((float*)pDestData)[j] = ((float*)pMatrix)[j * 4 + i];
2619        }
2620        pDestData += SType::c_RegisterSize;
2621    }
2622}
2623
2624template<bool Transpose>
2625static void GetMatrixTransposeHelper(_In_ const SType *pType, _In_reads_bytes_(64) uint8_t *pSrcData, _Out_writes_(16) float* pMatrix)
2626{
2627    uint32_t registers, entries;
2628
2629    if (Transpose)
2630    {
2631        // row major
2632        registers = pType->NumericType.Rows;
2633        entries = pType->NumericType.Columns;
2634    }
2635    else
2636    {
2637        // column major
2638        registers = pType->NumericType.Columns;
2639        entries = pType->NumericType.Rows;
2640    }
2641    _Analysis_assume_( registers <= 4 );
2642    _Analysis_assume_( entries <= 4 );
2643
2644    for (size_t i = 0; i < registers; ++ i)
2645    {
2646        for (size_t j = 0; j < entries; ++ j)
2647        {
2648            ((float*)pMatrix)[j * 4 + i] = ((float*)pSrcData)[j];
2649        }
2650        pSrcData += SType::c_RegisterSize;
2651    }
2652}
2653
2654template<bool Transpose, bool IsSetting, bool ExtraIndirection>
2655HRESULT DoMatrixArrayInternal(_In_ const SType *pType, _In_ uint32_t  TotalUnpackedSize,
2656                              _Out_ uint8_t *pEffectData,
2657                              void *pMatrixData,
2658                              _In_ uint32_t Offset, _In_ uint32_t Count, _In_z_ LPCSTR pFuncName)
2659{
2660    HRESULT hr = S_OK;
2661
2662#ifdef _DEBUG
2663#pragma warning( suppress : 6001 )
2664    if (!AreBoundsValid(Offset, Count, pMatrixData, pType, TotalUnpackedSize))
2665    {
2666        DPF(0, "%s: Invalid range specified", pFuncName);
2667        VH(E_INVALIDARG);
2668    }
2669#else
2670    UNREFERENCED_PARAMETER(TotalUnpackedSize);
2671    UNREFERENCED_PARAMETER(pFuncName);
2672#endif
2673
2674    if ((pType->NumericType.IsColumnMajor && Transpose) || (!pType->NumericType.IsColumnMajor && !Transpose))
2675    {
2676        // fast path
2677        uint32_t  dataSize;
2678        if (Transpose)
2679        {
2680            dataSize = ((pType->NumericType.Columns - 1) * 4 + pType->NumericType.Rows) * SType::c_ScalarSize;
2681        }
2682        else
2683        {
2684            dataSize = ((pType->NumericType.Rows - 1) * 4 + pType->NumericType.Columns) * SType::c_ScalarSize;
2685        }
2686
2687        for (size_t i = 0; i < Count; ++ i)
2688        {
2689            CEffectMatrix *pMatrix;
2690            if (ExtraIndirection)
2691            {
2692                pMatrix = ((CEffectMatrix **)pMatrixData)[i];
2693                if (!pMatrix)
2694                {
2695                    continue;
2696                }
2697            }
2698            else
2699            {
2700                pMatrix = ((CEffectMatrix *)pMatrixData) + i;
2701            }
2702
2703            if (IsSetting)
2704            {
2705                memcpy(pEffectData + pType->Stride * (i + Offset), pMatrix, dataSize);
2706            }
2707            else
2708            {
2709                memcpy(pMatrix, pEffectData + pType->Stride * (i + Offset), dataSize);
2710            }
2711        }
2712    }
2713    else
2714    {
2715        // slow path
2716        for (size_t i = 0; i < Count; ++ i)
2717        {
2718            CEffectMatrix *pMatrix;
2719            if (ExtraIndirection)
2720            {
2721                pMatrix = ((CEffectMatrix **)pMatrixData)[i];
2722                if (!pMatrix)
2723                {
2724                    continue;
2725                }
2726            }
2727            else
2728            {
2729                pMatrix = ((CEffectMatrix *)pMatrixData) + i;
2730            }
2731
2732            if (IsSetting)
2733            {
2734                SetMatrixTransposeHelper<Transpose>(pType, pEffectData + pType->Stride * (i + Offset), (float*) pMatrix);
2735            }
2736            else
2737            {
2738                GetMatrixTransposeHelper<Transpose>(pType, pEffectData + pType->Stride * (i + Offset), (float*) pMatrix);
2739            }
2740        }
2741    }
2742
2743lExit:
2744    return hr;
2745}
2746#pragma warning (pop)
2747
2748template<typename IBaseInterface, bool IsAnnotation>
2749_Use_decl_annotations_
2750HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::SetMatrix(const float *pData)
2751{
2752    static LPCSTR pFuncName = "ID3DX11EffectMatrixVariable::SetMatrix";
2753    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
2754    DirtyVariable();
2755    return DoMatrixArrayInternal<false, true, false>(pType, GetTotalUnpackedSize(),
2756        Data.pNumeric, const_cast<float*>(pData), 0, 1, pFuncName);
2757}
2758
2759template<typename IBaseInterface, bool IsAnnotation>
2760_Use_decl_annotations_
2761HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::GetMatrix(float *pData)
2762{
2763    return DoMatrixArrayInternal<false, false, false>(pType, GetTotalUnpackedSize(),
2764        Data.pNumeric, pData, 0, 1, "ID3DX11EffectMatrixVariable::GetMatrix");
2765}
2766
2767template<typename IBaseInterface, bool IsAnnotation>
2768_Use_decl_annotations_
2769HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::SetMatrixArray(const float *pData, uint32_t Offset, uint32_t Count)
2770{
2771    static LPCSTR pFuncName = "ID3DX11EffectMatrixVariable::SetMatrixArray";
2772    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
2773    DirtyVariable();
2774    return DoMatrixArrayInternal<false, true, false>(pType, GetTotalUnpackedSize(),
2775        Data.pNumeric, const_cast<float*>(pData), Offset, Count, "ID3DX11EffectMatrixVariable::SetMatrixArray");
2776}
2777
2778template<typename IBaseInterface, bool IsAnnotation>
2779_Use_decl_annotations_
2780HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::GetMatrixArray(float *pData, uint32_t Offset, uint32_t Count)
2781{
2782    return DoMatrixArrayInternal<false, false, false>(pType, GetTotalUnpackedSize(),
2783        Data.pNumeric, pData, Offset, Count, "ID3DX11EffectMatrixVariable::GetMatrixArray");
2784}
2785
2786template<typename IBaseInterface, bool IsAnnotation>
2787_Use_decl_annotations_
2788HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::SetMatrixPointerArray(const float **ppData, uint32_t Offset, uint32_t Count)
2789{
2790    static LPCSTR pFuncName = "ID3DX11EffectMatrixVariable::SetMatrixPointerArray";
2791    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
2792    DirtyVariable();
2793    return DoMatrixArrayInternal<false, true, true>(pType, GetTotalUnpackedSize(),
2794        Data.pNumeric, const_cast<float**>(ppData), Offset, Count, "ID3DX11EffectMatrixVariable::SetMatrixPointerArray");
2795}
2796
2797template<typename IBaseInterface, bool IsAnnotation>
2798_Use_decl_annotations_
2799HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::GetMatrixPointerArray(float **ppData, uint32_t Offset, uint32_t Count)
2800{
2801    return DoMatrixArrayInternal<false, false, true>(pType, GetTotalUnpackedSize(),
2802        Data.pNumeric, ppData, Offset, Count, "ID3DX11EffectMatrixVariable::GetMatrixPointerArray");
2803}
2804
2805template<typename IBaseInterface, bool IsAnnotation>
2806_Use_decl_annotations_
2807HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::SetMatrixTranspose(const float *pData)
2808{
2809    static LPCSTR pFuncName = "ID3DX11EffectMatrixVariable::SetMatrixTranspose";
2810    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
2811    DirtyVariable();
2812    return DoMatrixArrayInternal<true, true, false>(pType, GetTotalUnpackedSize(),
2813        Data.pNumeric, const_cast<float*>(pData), 0, 1, "ID3DX11EffectMatrixVariable::SetMatrixTranspose");
2814}
2815
2816template<typename IBaseInterface, bool IsAnnotation>
2817_Use_decl_annotations_
2818HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::GetMatrixTranspose(float *pData)
2819{
2820    return DoMatrixArrayInternal<true, false, false>(pType, GetTotalUnpackedSize(),
2821        Data.pNumeric, pData, 0, 1, "ID3DX11EffectMatrixVariable::GetMatrixTranspose");
2822}
2823
2824template<typename IBaseInterface, bool IsAnnotation>
2825_Use_decl_annotations_
2826HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::SetMatrixTransposeArray(const float *pData, uint32_t Offset, uint32_t Count)
2827{
2828    static LPCSTR pFuncName = "ID3DX11EffectMatrixVariable::SetMatrixTransposeArray";
2829    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
2830    DirtyVariable();
2831    return DoMatrixArrayInternal<true, true, false>(pType, GetTotalUnpackedSize(),
2832        Data.pNumeric, const_cast<float*>(pData), Offset, Count, "ID3DX11EffectMatrixVariable::SetMatrixTransposeArray");
2833}
2834
2835template<typename IBaseInterface, bool IsAnnotation>
2836_Use_decl_annotations_
2837HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::GetMatrixTransposeArray(float *pData, uint32_t Offset, uint32_t Count)
2838{
2839    return DoMatrixArrayInternal<true, false, false>(pType, GetTotalUnpackedSize(),
2840        Data.pNumeric, pData, Offset, Count, "ID3DX11EffectMatrixVariable::GetMatrixTransposeArray");
2841}
2842
2843template<typename IBaseInterface, bool IsAnnotation>
2844_Use_decl_annotations_
2845HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::SetMatrixTransposePointerArray(const float **ppData, uint32_t Offset, uint32_t Count)
2846{
2847    static LPCSTR pFuncName = "ID3DX11EffectMatrixVariable::SetMatrixTransposePointerArray";
2848    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
2849    DirtyVariable();
2850    return DoMatrixArrayInternal<true, true, true>(pType, GetTotalUnpackedSize(),
2851        Data.pNumeric, const_cast<float**>(ppData), Offset, Count, "ID3DX11EffectMatrixVariable::SetMatrixTransposePointerArray");
2852}
2853
2854template<typename IBaseInterface, bool IsAnnotation>
2855_Use_decl_annotations_
2856HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::GetMatrixTransposePointerArray(float **ppData, uint32_t Offset, uint32_t Count)
2857{
2858    return DoMatrixArrayInternal<true, false, true>(pType, GetTotalUnpackedSize(),
2859        Data.pNumeric, ppData, Offset, Count, "ID3DX11EffectMatrixVariable::GetMatrixTransposePointerArray");
2860}
2861
2862// Optimize commonly used fast paths
2863// (non-annotations only!)
2864template<typename IBaseInterface, bool IsColumnMajor>
2865struct TMatrix4x4Variable : public TMatrixVariable<IBaseInterface, false>
2866{
2867    STDMETHOD(SetMatrix)(_In_reads_(16) const float *pData) override;
2868    STDMETHOD(GetMatrix)(_Out_writes_(16) float *pData) override;
2869
2870    STDMETHOD(SetMatrixArray)(_In_reads_(16*Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
2871    STDMETHOD(GetMatrixArray)(_Out_writes_(16*Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
2872
2873    STDMETHOD(SetMatrixTranspose)(_In_reads_(16) const float *pData) override;
2874    STDMETHOD(GetMatrixTranspose)(_Out_writes_(16) float *pData) override;
2875
2876    STDMETHOD(SetMatrixTransposeArray)(_In_reads_(16*Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
2877    STDMETHOD(GetMatrixTransposeArray)(_Out_writes_(16*Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
2878};
2879
2880inline static void Matrix4x4TransposeHelper(_In_reads_bytes_(64) const void *pSrc, _Out_writes_bytes_(64) void *pDst)
2881{
2882    uint8_t *pDestData = (uint8_t*)pDst;
2883    uint32_t *pMatrix = (uint32_t*)pSrc;
2884
2885    ((uint32_t*)pDestData)[0 * 4 + 0] = pMatrix[0 * 4 + 0];
2886    ((uint32_t*)pDestData)[0 * 4 + 1] = pMatrix[1 * 4 + 0];
2887    ((uint32_t*)pDestData)[0 * 4 + 2] = pMatrix[2 * 4 + 0];
2888    ((uint32_t*)pDestData)[0 * 4 + 3] = pMatrix[3 * 4 + 0];
2889
2890    ((uint32_t*)pDestData)[1 * 4 + 0] = pMatrix[0 * 4 + 1];
2891    ((uint32_t*)pDestData)[1 * 4 + 1] = pMatrix[1 * 4 + 1];
2892    ((uint32_t*)pDestData)[1 * 4 + 2] = pMatrix[2 * 4 + 1];
2893    ((uint32_t*)pDestData)[1 * 4 + 3] = pMatrix[3 * 4 + 1];
2894
2895    ((uint32_t*)pDestData)[2 * 4 + 0] = pMatrix[0 * 4 + 2];
2896    ((uint32_t*)pDestData)[2 * 4 + 1] = pMatrix[1 * 4 + 2];
2897    ((uint32_t*)pDestData)[2 * 4 + 2] = pMatrix[2 * 4 + 2];
2898    ((uint32_t*)pDestData)[2 * 4 + 3] = pMatrix[3 * 4 + 2];
2899
2900    ((uint32_t*)pDestData)[3 * 4 + 0] = pMatrix[0 * 4 + 3];
2901    ((uint32_t*)pDestData)[3 * 4 + 1] = pMatrix[1 * 4 + 3];
2902    ((uint32_t*)pDestData)[3 * 4 + 2] = pMatrix[2 * 4 + 3];
2903    ((uint32_t*)pDestData)[3 * 4 + 3] = pMatrix[3 * 4 + 3];
2904}
2905
2906inline static void Matrix4x4Copy(_In_reads_bytes_(64) const void *pSrc, _Out_writes_bytes_(64) void *pDst)
2907{
2908#if 1
2909    // In tests, this path ended up generating faster code both on x86 and x64
2910    // T1 - Matrix4x4Copy - this path
2911    // T2 - Matrix4x4Transpose
2912    // T1: 1.88 T2: 1.92 - with 32 bit copies
2913    // T1: 1.85 T2: 1.80 - with 64 bit copies
2914
2915    uint64_t *pDestData = (uint64_t*)pDst;
2916    uint64_t *pMatrix = (uint64_t*)pSrc;
2917
2918    pDestData[0 * 4 + 0] = pMatrix[0 * 4 + 0];
2919    pDestData[0 * 4 + 1] = pMatrix[0 * 4 + 1];
2920    pDestData[0 * 4 + 2] = pMatrix[0 * 4 + 2];
2921    pDestData[0 * 4 + 3] = pMatrix[0 * 4 + 3];
2922
2923    pDestData[1 * 4 + 0] = pMatrix[1 * 4 + 0];
2924    pDestData[1 * 4 + 1] = pMatrix[1 * 4 + 1];
2925    pDestData[1 * 4 + 2] = pMatrix[1 * 4 + 2];
2926    pDestData[1 * 4 + 3] = pMatrix[1 * 4 + 3];
2927#else
2928    uint32_t *pDestData = (uint32_t*)pDst;
2929    uint32_t *pMatrix = (uint32_t*)pSrc;
2930
2931    pDestData[0 * 4 + 0] = pMatrix[0 * 4 + 0];
2932    pDestData[0 * 4 + 1] = pMatrix[0 * 4 + 1];
2933    pDestData[0 * 4 + 2] = pMatrix[0 * 4 + 2];
2934    pDestData[0 * 4 + 3] = pMatrix[0 * 4 + 3];
2935
2936    pDestData[1 * 4 + 0] = pMatrix[1 * 4 + 0];
2937    pDestData[1 * 4 + 1] = pMatrix[1 * 4 + 1];
2938    pDestData[1 * 4 + 2] = pMatrix[1 * 4 + 2];
2939    pDestData[1 * 4 + 3] = pMatrix[1 * 4 + 3];
2940
2941    pDestData[2 * 4 + 0] = pMatrix[2 * 4 + 0];
2942    pDestData[2 * 4 + 1] = pMatrix[2 * 4 + 1];
2943    pDestData[2 * 4 + 2] = pMatrix[2 * 4 + 2];
2944    pDestData[2 * 4 + 3] = pMatrix[2 * 4 + 3];
2945
2946    pDestData[3 * 4 + 0] = pMatrix[3 * 4 + 0];
2947    pDestData[3 * 4 + 1] = pMatrix[3 * 4 + 1];
2948    pDestData[3 * 4 + 2] = pMatrix[3 * 4 + 2];
2949    pDestData[3 * 4 + 3] = pMatrix[3 * 4 + 3];
2950#endif
2951}
2952
2953
2954// Note that branches in this code is based on template parameters and will be compiled out
2955#pragma warning (push)
2956#pragma warning (disable : 6101)
2957template<bool IsColumnMajor, bool Transpose, bool IsSetting>
2958inline HRESULT DoMatrix4x4ArrayInternal(_In_ uint8_t *pEffectData,
2959                                        _When_(IsSetting, _In_reads_bytes_(64 * Count))
2960                                        _When_(!IsSetting, _Out_writes_bytes_(64 * Count))
2961                                        void *pMatrixData,
2962                                        _In_ uint32_t Offset, _In_ uint32_t Count
2963#ifdef _DEBUG
2964                                        , _In_ const SType *pType, _In_ uint32_t  TotalUnpackedSize, _In_z_ LPCSTR pFuncName
2965#endif
2966
2967                                        )
2968{
2969    HRESULT hr = S_OK;
2970
2971#ifdef _DEBUG
2972#pragma warning( suppress : 6001 )
2973    if (!AreBoundsValid(Offset, Count, pMatrixData, pType, TotalUnpackedSize))
2974    {
2975        DPF(0, "%s: Invalid range specified", pFuncName);
2976        VH(E_INVALIDARG);
2977    }
2978
2979    assert(pType->NumericType.IsColumnMajor == IsColumnMajor && pType->Stride == (4 * SType::c_RegisterSize));
2980#endif
2981
2982    if ((IsColumnMajor && Transpose) || (!IsColumnMajor && !Transpose))
2983    {
2984        // fast path
2985        for (size_t i = 0; i < Count; ++ i)
2986        {
2987            CEffectMatrix *pMatrix = ((CEffectMatrix *)pMatrixData) + i;
2988
2989            if (IsSetting)
2990            {
2991                Matrix4x4Copy(pMatrix, pEffectData + 4 * SType::c_RegisterSize * (i + Offset));
2992            }
2993            else
2994            {
2995                Matrix4x4Copy(pEffectData + 4 * SType::c_RegisterSize * (i + Offset), pMatrix);
2996            }
2997        }
2998    }
2999    else
3000    {
3001        // slow path
3002        for (size_t i = 0; i < Count; ++ i)
3003        {
3004            CEffectMatrix *pMatrix = ((CEffectMatrix *)pMatrixData) + i;
3005
3006            if (IsSetting)
3007            {
3008                Matrix4x4TransposeHelper((float*) pMatrix, pEffectData + 4 * SType::c_RegisterSize * (i + Offset));
3009            }
3010            else
3011            {
3012                Matrix4x4TransposeHelper(pEffectData + 4 * SType::c_RegisterSize * (i + Offset), (float*) pMatrix);
3013            }
3014        }
3015    }
3016
3017lExit:
3018    return hr;
3019}
3020#pragma warning (pop)
3021
3022template<typename IBaseInterface, bool IsColumnMajor>
3023_Use_decl_annotations_
3024HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::SetMatrix(const float *pData)
3025{
3026    DirtyVariable();
3027    return DoMatrix4x4ArrayInternal<IsColumnMajor, false, true>(Data.pNumeric, const_cast<float*>(pData), 0, 1
3028#ifdef _DEBUG
3029        , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::SetMatrix");
3030#else
3031        );
3032#endif
3033}
3034
3035template<typename IBaseInterface, bool IsColumnMajor>
3036_Use_decl_annotations_
3037HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::GetMatrix(float *pData)
3038{
3039    return DoMatrix4x4ArrayInternal<IsColumnMajor, false, false>(Data.pNumeric, pData, 0, 1
3040#ifdef _DEBUG
3041        , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::GetMatrix");
3042#else
3043        );
3044#endif
3045}
3046
3047template<typename IBaseInterface, bool IsColumnMajor>
3048_Use_decl_annotations_
3049HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::SetMatrixArray(const float *pData, uint32_t Offset, uint32_t Count)
3050{
3051    DirtyVariable();
3052    return DoMatrix4x4ArrayInternal<IsColumnMajor, false, true>(Data.pNumeric, const_cast<float*>(pData), Offset, Count
3053#ifdef _DEBUG
3054        , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::SetMatrixArray");
3055#else
3056        );
3057#endif
3058}
3059
3060template<typename IBaseInterface, bool IsColumnMajor>
3061_Use_decl_annotations_
3062HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::GetMatrixArray(float *pData, uint32_t Offset, uint32_t Count)
3063{
3064    return DoMatrix4x4ArrayInternal<IsColumnMajor, false, false>(Data.pNumeric, pData, Offset, Count
3065#ifdef _DEBUG
3066        , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::GetMatrixArray");
3067#else
3068        );
3069#endif
3070}
3071
3072template<typename IBaseInterface, bool IsColumnMajor>
3073_Use_decl_annotations_
3074HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::SetMatrixTranspose(const float *pData)
3075{
3076    DirtyVariable();
3077    return DoMatrix4x4ArrayInternal<IsColumnMajor, true, true>(Data.pNumeric, const_cast<float*>(pData), 0, 1
3078#ifdef _DEBUG
3079        , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::SetMatrixTranspose");
3080#else
3081        );
3082#endif
3083}
3084
3085template<typename IBaseInterface, bool IsColumnMajor>
3086_Use_decl_annotations_
3087HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::GetMatrixTranspose(float *pData)
3088{
3089    return DoMatrix4x4ArrayInternal<IsColumnMajor, true, false>(Data.pNumeric, pData, 0, 1
3090#ifdef _DEBUG
3091        , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::GetMatrixTranspose");
3092#else
3093        );
3094#endif
3095}
3096
3097template<typename IBaseInterface, bool IsColumnMajor>
3098_Use_decl_annotations_
3099HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::SetMatrixTransposeArray(const float *pData, uint32_t Offset, uint32_t Count)
3100{
3101    DirtyVariable();
3102    return DoMatrix4x4ArrayInternal<IsColumnMajor, true, true>(Data.pNumeric, const_cast<float*>(pData), Offset, Count
3103#ifdef _DEBUG
3104        , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::SetMatrixTransposeArray");
3105#else
3106        );
3107#endif
3108}
3109
3110template<typename IBaseInterface, bool IsColumnMajor>
3111_Use_decl_annotations_
3112HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::GetMatrixTransposeArray(float *pData, uint32_t Offset, uint32_t Count)
3113{
3114    return DoMatrix4x4ArrayInternal<IsColumnMajor, true, false>(Data.pNumeric, pData, Offset, Count
3115#ifdef _DEBUG
3116        , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::GetMatrixTransposeArray");
3117#else
3118        );
3119#endif
3120}
3121
3122#ifdef _DEBUG
3123
3124// Useful object macro to check bounds and parameters
3125#define CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, Pointer) \
3126    HRESULT hr = S_OK; \
3127    VERIFYPARAMETER(Pointer) \
3128    uint32_t elements = IsArray() ? pType->Elements : 1; \
3129    \
3130    if ((Offset + Count < Offset) || (elements < Offset + Count)) \
3131    { \
3132        DPF(0, "%s: Invalid range specified", pFuncName); \
3133        VH(E_INVALIDARG); \
3134    } \
3135
3136#define CHECK_OBJECT_SCALAR_BOUNDS(Index, Pointer) \
3137    HRESULT hr = S_OK; \
3138    VERIFYPARAMETER(Pointer) \
3139    uint32_t elements = IsArray() ? pType->Elements : 1; \
3140    \
3141    if (Index >= elements) \
3142    { \
3143        DPF(0, "%s: Invalid index specified", pFuncName); \
3144        VH(E_INVALIDARG); \
3145    } \
3146
3147#define CHECK_SCALAR_BOUNDS(Index) \
3148    HRESULT hr = S_OK; \
3149    uint32_t elements = IsArray() ? pType->Elements : 1; \
3150    \
3151    if (Index >= elements) \
3152{ \
3153    DPF(0, "%s: Invalid index specified", pFuncName); \
3154    VH(E_INVALIDARG); \
3155} \
3156
3157#else // _DEBUG
3158
3159#define CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, Pointer) \
3160    HRESULT hr = S_OK; \
3161
3162#define CHECK_OBJECT_SCALAR_BOUNDS(Index, Pointer) \
3163    HRESULT hr = S_OK; \
3164
3165#define CHECK_SCALAR_BOUNDS(Index) \
3166    HRESULT hr = S_OK; \
3167
3168#endif // _DEBUG
3169
3170//////////////////////////////////////////////////////////////////////////
3171// ID3DX11EffectStringVariable (TStringVariable implementation)
3172//////////////////////////////////////////////////////////////////////////
3173
3174template<typename IBaseInterface, bool IsAnnotation>
3175struct TStringVariable : public IBaseInterface
3176{
3177    STDMETHOD(GetString)(_Outptr_result_z_ LPCSTR *ppString) override;
3178    STDMETHOD(GetStringArray)( _Out_writes_(Count) LPCSTR *ppStrings, _In_ uint32_t Offset, _In_ uint32_t Count ) override;
3179};
3180
3181template<typename IBaseInterface, bool IsAnnotation>
3182_Use_decl_annotations_
3183HRESULT TStringVariable<IBaseInterface, IsAnnotation>::GetString(LPCSTR *ppString)
3184{
3185    HRESULT hr = S_OK;
3186    static LPCSTR pFuncName = "ID3DX11EffectStringVariable::GetString";
3187
3188    VERIFYPARAMETER(ppString);
3189
3190    if (GetTopLevelEntity()->pEffect->IsOptimized())
3191    {
3192        DPF(0, "%s: Effect has been Optimize()'ed; all string/reflection data has been deleted", pFuncName);
3193        return D3DERR_INVALIDCALL;
3194    }
3195
3196    assert(Data.pString != 0);
3197    _Analysis_assume_(Data.pString != 0);
3198
3199    *ppString = Data.pString->pString;
3200
3201lExit:
3202    return hr;
3203}
3204
3205template<typename IBaseInterface, bool IsAnnotation>
3206_Use_decl_annotations_
3207#pragma warning(suppress : 6054)
3208HRESULT TStringVariable<IBaseInterface, IsAnnotation>::GetStringArray( LPCSTR *ppStrings, uint32_t Offset, uint32_t Count)
3209{
3210    static LPCSTR pFuncName = "ID3DX11EffectStringVariable::GetStringArray";
3211
3212    CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppStrings);
3213
3214    if (GetTopLevelEntity()->pEffect->IsOptimized())
3215    {
3216        DPF(0, "%s: Effect has been Optimize()'ed; all string/reflection data has been deleted", pFuncName);
3217        return D3DERR_INVALIDCALL;
3218    }
3219
3220    assert(Data.pString != 0);
3221    _Analysis_assume_(Data.pString != 0);
3222
3223    for (size_t i = 0; i < Count; ++ i)
3224    {
3225        ppStrings[i] = (Data.pString + Offset + i)->pString;
3226    }
3227
3228lExit:
3229    return hr;
3230}
3231
3232//////////////////////////////////////////////////////////////////////////
3233// ID3DX11EffectClassInstanceVariable (TClassInstanceVariable implementation)
3234//////////////////////////////////////////////////////////////////////////
3235
3236template<typename IBaseInterface>
3237struct TClassInstanceVariable : public IBaseInterface
3238{
3239    STDMETHOD(GetClassInstance)(_Outptr_ ID3D11ClassInstance **ppClassInstance) override;
3240};
3241
3242template<typename IBaseClassInstance>
3243HRESULT TClassInstanceVariable<IBaseClassInstance>::GetClassInstance(_Outptr_ ID3D11ClassInstance** ppClassInstance)
3244{
3245    HRESULT hr = S_OK;
3246    static LPCSTR pFuncName = "ID3DX11EffectClassInstanceVariable::GetClassInstance";
3247
3248    assert( pMemberData != 0 && pMemberData->Data.pD3DClassInstance != 0);
3249    _Analysis_assume_( pMemberData != 0 && pMemberData->Data.pD3DClassInstance != 0);
3250    *ppClassInstance = pMemberData->Data.pD3DClassInstance;
3251    SAFE_ADDREF(*ppClassInstance);
3252
3253lExit:
3254    return hr;
3255}
3256
3257//////////////////////////////////////////////////////////////////////////
3258// ID3DX11EffectInterfaceeVariable (TInterfaceVariable implementation)
3259//////////////////////////////////////////////////////////////////////////
3260
3261template<typename IBaseInterface>
3262struct TInterfaceVariable : public IBaseInterface
3263{
3264    STDMETHOD(SetClassInstance)(_In_ ID3DX11EffectClassInstanceVariable *pEffectClassInstance) override;
3265    STDMETHOD(GetClassInstance)(_Outptr_ ID3DX11EffectClassInstanceVariable **ppEffectClassInstance) override;
3266};
3267
3268template<typename IBaseInterface>
3269HRESULT TInterfaceVariable<IBaseInterface>::SetClassInstance(_In_ ID3DX11EffectClassInstanceVariable *pEffectClassInstance)
3270{
3271    HRESULT hr = S_OK;
3272    static LPCSTR pFuncName = "ID3DX11EffectInterfaceVariable::SetClassInstance";
3273
3274    // Note that we don't check if the types are compatible.  The debug layer will complain if it is.
3275    // IsValid() will not catch type mismatches.
3276    SClassInstanceGlobalVariable* pCI = (SClassInstanceGlobalVariable*)pEffectClassInstance;
3277    Data.pInterface->pClassInstance = pCI;
3278
3279lExit:
3280    return hr;
3281}
3282
3283template<typename IBaseInterface>
3284HRESULT TInterfaceVariable<IBaseInterface>::GetClassInstance(_Outptr_ ID3DX11EffectClassInstanceVariable **ppEffectClassInstance)
3285{
3286    HRESULT hr = S_OK;
3287    static LPCSTR pFuncName = "ID3DX11EffectInterfaceVariable::GetClassInstance";
3288
3289#ifdef _DEBUG
3290    VERIFYPARAMETER(ppEffectClassInstance);
3291#endif
3292
3293    *ppEffectClassInstance = Data.pInterface->pClassInstance;
3294
3295lExit:
3296    return hr;
3297}
3298
3299//////////////////////////////////////////////////////////////////////////
3300// ID3DX11EffectShaderResourceVariable (TShaderResourceVariable implementation)
3301//////////////////////////////////////////////////////////////////////////
3302
3303template<typename IBaseInterface>
3304struct TShaderResourceVariable : public IBaseInterface
3305{
3306    STDMETHOD(SetResource)(_In_ ID3D11ShaderResourceView *pResource) override;
3307    STDMETHOD(GetResource)(_Outptr_ ID3D11ShaderResourceView **ppResource) override;
3308
3309    STDMETHOD(SetResourceArray)(_In_reads_(Count) ID3D11ShaderResourceView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
3310    STDMETHOD(GetResourceArray)(_Out_writes_(Count) ID3D11ShaderResourceView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
3311};
3312
3313static LPCSTR GetTextureTypeNameFromEnum(_In_ EObjectType ObjectType)
3314{
3315    switch (ObjectType)
3316    {
3317    case EOT_Buffer:
3318        return "Buffer";
3319    case EOT_Texture:
3320        return "texture";
3321    case EOT_Texture1D:
3322    case EOT_Texture1DArray:
3323        return "Texture1D";
3324    case EOT_Texture2DMS:
3325    case EOT_Texture2DMSArray:
3326        return "Texture2DMS";
3327    case EOT_Texture2D:
3328    case EOT_Texture2DArray:
3329        return "Texture2D";
3330    case EOT_Texture3D:
3331        return "Texture3D";
3332    case EOT_TextureCube:
3333        return "TextureCube";
3334    case EOT_TextureCubeArray:
3335        return "TextureCubeArray";
3336    case EOT_RWTexture1D:
3337    case EOT_RWTexture1DArray:
3338        return "RWTexture1D";
3339    case EOT_RWTexture2D:
3340    case EOT_RWTexture2DArray:
3341        return "RWTexture2D";
3342    case EOT_RWTexture3D:
3343        return "RWTexture3D";
3344    case EOT_RWBuffer:
3345        return "RWBuffer";
3346    case EOT_ByteAddressBuffer:
3347        return "ByteAddressBuffer";
3348    case EOT_RWByteAddressBuffer:
3349        return "RWByteAddressBuffer";
3350    case EOT_StructuredBuffer:
3351        return "StructuredBuffe";
3352    case EOT_RWStructuredBuffer:
3353        return "RWStructuredBuffer";
3354    case EOT_RWStructuredBufferAlloc:
3355        return "RWStructuredBufferAlloc";
3356    case EOT_RWStructuredBufferConsume:
3357        return "RWStructuredBufferConsume";
3358    case EOT_AppendStructuredBuffer:
3359        return "AppendStructuredBuffer";
3360    case EOT_ConsumeStructuredBuffer:
3361        return "ConsumeStructuredBuffer";
3362    }
3363    return "<unknown texture format>";
3364}
3365
3366static LPCSTR GetResourceDimensionNameFromEnum(_In_ D3D11_RESOURCE_DIMENSION ResourceDimension)
3367{
3368    switch (ResourceDimension)
3369    {
3370    case D3D11_RESOURCE_DIMENSION_BUFFER:
3371        return "Buffer";
3372    case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
3373        return "Texture1D";
3374    case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
3375        return "Texture2D";
3376    case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
3377        return "Texture3D";
3378    }
3379    return "<unknown texture format>";
3380}
3381
3382static LPCSTR GetSRVDimensionNameFromEnum(_In_ D3D11_SRV_DIMENSION ViewDimension)
3383{
3384    switch (ViewDimension)
3385    {
3386    case D3D11_SRV_DIMENSION_BUFFER:
3387    case D3D11_SRV_DIMENSION_BUFFEREX:
3388        return "Buffer";
3389    case D3D11_SRV_DIMENSION_TEXTURE1D:
3390        return "Texture1D";
3391    case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
3392        return "Texture1DArray";
3393    case D3D11_SRV_DIMENSION_TEXTURE2D:
3394        return "Texture2D";
3395    case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
3396        return "Texture2DArray";
3397    case D3D11_SRV_DIMENSION_TEXTURE2DMS:
3398        return "Texture2DMS";
3399    case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
3400        return "Texture2DMSArray";
3401    case D3D11_SRV_DIMENSION_TEXTURE3D:
3402        return "Texture3D";
3403    case D3D11_SRV_DIMENSION_TEXTURECUBE:
3404        return "TextureCube";
3405    }
3406    return "<unknown texture format>";
3407}
3408
3409static LPCSTR GetUAVDimensionNameFromEnum(_In_ D3D11_UAV_DIMENSION ViewDimension)
3410{
3411    switch (ViewDimension)
3412    {
3413    case D3D11_UAV_DIMENSION_BUFFER:
3414        return "Buffer";
3415    case D3D11_UAV_DIMENSION_TEXTURE1D:
3416        return "RWTexture1D";
3417    case D3D11_UAV_DIMENSION_TEXTURE1DARRAY:
3418        return "RWTexture1DArray";
3419    case D3D11_UAV_DIMENSION_TEXTURE2D:
3420        return "RWTexture2D";
3421    case D3D11_UAV_DIMENSION_TEXTURE2DARRAY:
3422        return "RWTexture2DArray";
3423    case D3D11_UAV_DIMENSION_TEXTURE3D:
3424        return "RWTexture3D";
3425    }
3426    return "<unknown texture format>";
3427}
3428
3429static LPCSTR GetRTVDimensionNameFromEnum(_In_ D3D11_RTV_DIMENSION ViewDimension)
3430{
3431    switch (ViewDimension)
3432    {
3433    case D3D11_RTV_DIMENSION_BUFFER:
3434        return "Buffer";
3435    case D3D11_RTV_DIMENSION_TEXTURE1D:
3436        return "Texture1D";
3437    case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
3438        return "Texture1DArray";
3439    case D3D11_RTV_DIMENSION_TEXTURE2D:
3440        return "Texture2D";
3441    case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
3442        return "Texture2DArray";
3443    case D3D11_RTV_DIMENSION_TEXTURE2DMS:
3444        return "Texture2DMS";
3445    case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
3446        return "Texture2DMSArray";
3447    case D3D11_RTV_DIMENSION_TEXTURE3D:
3448        return "Texture3D";
3449    }
3450    return "<unknown texture format>";
3451}
3452
3453static LPCSTR GetDSVDimensionNameFromEnum(_In_ D3D11_DSV_DIMENSION ViewDimension)
3454{
3455    switch (ViewDimension)
3456    {
3457    case D3D11_DSV_DIMENSION_TEXTURE1D:
3458        return "Texture1D";
3459    case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
3460        return "Texture1DArray";
3461    case D3D11_DSV_DIMENSION_TEXTURE2D:
3462        return "Texture2D";
3463    case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
3464        return "Texture2DArray";
3465    case D3D11_DSV_DIMENSION_TEXTURE2DMS:
3466        return "Texture2DMS";
3467    case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
3468        return "Texture2DMSArray";
3469    }
3470    return "<unknown texture format>";
3471}
3472
3473static HRESULT ValidateTextureType(_In_ ID3D11ShaderResourceView *pView, _In_ EObjectType ObjectType, _In_z_ LPCSTR pFuncName)
3474{
3475    if (nullptr != pView)
3476    {
3477        D3D11_SHADER_RESOURCE_VIEW_DESC desc;
3478        pView->GetDesc(&desc);
3479        switch (ObjectType)
3480        {
3481        case EOT_Texture:
3482            if (desc.ViewDimension != D3D11_SRV_DIMENSION_BUFFER && desc.ViewDimension != D3D11_SRV_DIMENSION_BUFFEREX)
3483                return S_OK;
3484            break;
3485        case EOT_Buffer:
3486            if (desc.ViewDimension != D3D11_SRV_DIMENSION_BUFFER && desc.ViewDimension != D3D11_SRV_DIMENSION_BUFFEREX)
3487                break;
3488            if (desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX && (desc.BufferEx.Flags & D3D11_BUFFEREX_SRV_FLAG_RAW))
3489            {
3490                DPF(0, "%s: Resource type mismatch; %s expected, ByteAddressBuffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
3491                return E_INVALIDARG;
3492            }
3493            else
3494            {
3495                ID3D11Buffer* pBuffer = nullptr;
3496                pView->GetResource( (ID3D11Resource**)&pBuffer );
3497                assert( pBuffer != nullptr );
3498                D3D11_BUFFER_DESC BufDesc;
3499                pBuffer->GetDesc( &BufDesc );
3500                SAFE_RELEASE( pBuffer );
3501                if( BufDesc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED )
3502                {
3503                    DPF(0, "%s: Resource type mismatch; %s expected, StructuredBuffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
3504                    return E_INVALIDARG;
3505                }
3506                else
3507                {
3508                    return S_OK;
3509                }
3510            }
3511            break;
3512        case EOT_Texture1D:
3513        case EOT_Texture1DArray:
3514            if (desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1D ||
3515                desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1DARRAY)
3516                return S_OK;
3517            break;
3518        case EOT_Texture2D:
3519        case EOT_Texture2DArray:
3520            if (desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2D ||
3521                desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DARRAY)
3522                return S_OK;
3523            break;
3524        case EOT_Texture2DMS:
3525        case EOT_Texture2DMSArray:
3526            if (desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMS ||
3527                desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY)
3528                return S_OK;
3529            break;
3530        case EOT_Texture3D:
3531            if (desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D)
3532                return S_OK;
3533            break;
3534        case EOT_TextureCube:
3535        case EOT_TextureCubeArray:
3536            if (desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBE ||
3537                desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBEARRAY)
3538                return S_OK;
3539            break;
3540        case EOT_ByteAddressBuffer:
3541            if (desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX && (desc.BufferEx.Flags & D3D11_BUFFEREX_SRV_FLAG_RAW))
3542                return S_OK;
3543            break;
3544        case EOT_StructuredBuffer:
3545            if (desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX || desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFER)
3546            {
3547                ID3D11Buffer* pBuffer = nullptr;
3548                pView->GetResource( (ID3D11Resource**)&pBuffer );
3549                assert( pBuffer != nullptr );
3550                D3D11_BUFFER_DESC BufDesc;
3551                pBuffer->GetDesc( &BufDesc );
3552                SAFE_RELEASE( pBuffer );
3553                if( BufDesc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED )
3554                {
3555                    return S_OK;
3556                }
3557                else
3558                {
3559                    DPF(0, "%s: Resource type mismatch; %s expected, non-structured Buffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
3560                    return E_INVALIDARG;
3561                }
3562            }
3563            break;
3564        default:
3565            assert(0); // internal error, should never get here
3566            return E_FAIL;
3567        }
3568
3569
3570        DPF(0, "%s: Resource type mismatch; %s expected, %s provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType), GetSRVDimensionNameFromEnum(desc.ViewDimension));
3571        return E_INVALIDARG;
3572    }
3573    return S_OK;
3574}
3575
3576template<typename IBaseInterface>
3577_Use_decl_annotations_
3578HRESULT TShaderResourceVariable<IBaseInterface>::SetResource(ID3D11ShaderResourceView *pResource)
3579{
3580    HRESULT hr = S_OK;
3581
3582#ifdef _DEBUG
3583    static LPCSTR pFuncName = "ID3DX11EffectShaderResourceVariable::SetResource";
3584
3585    VH(ValidateTextureType(pResource, pType->ObjectType, pFuncName));
3586#endif
3587
3588    // Texture variables don't need to be dirtied.
3589    SAFE_ADDREF(pResource);
3590    SAFE_RELEASE(Data.pShaderResource->pShaderResource);
3591    Data.pShaderResource->pShaderResource = pResource;
3592
3593lExit:
3594    return hr;
3595}
3596
3597template<typename IBaseInterface>
3598_Use_decl_annotations_
3599HRESULT TShaderResourceVariable<IBaseInterface>::GetResource(ID3D11ShaderResourceView **ppResource)
3600{
3601    HRESULT hr = S_OK;
3602
3603#ifdef _DEBUG
3604    static LPCSTR pFuncName = "ID3DX11EffectShaderResourceVariable::GetResource";
3605
3606    VERIFYPARAMETER(ppResource);
3607#endif
3608
3609    assert(Data.pShaderResource != 0 && Data.pShaderResource->pShaderResource != 0);
3610    _Analysis_assume_(Data.pShaderResource != 0 && Data.pShaderResource->pShaderResource != 0);
3611    *ppResource = Data.pShaderResource->pShaderResource;
3612    SAFE_ADDREF(*ppResource);
3613
3614lExit:
3615    return hr;
3616}
3617
3618template<typename IBaseInterface>
3619_Use_decl_annotations_
3620HRESULT TShaderResourceVariable<IBaseInterface>::SetResourceArray(ID3D11ShaderResourceView **ppResources, uint32_t Offset, uint32_t Count)
3621{
3622    static LPCSTR pFuncName = "ID3DX11EffectShaderResourceVariable::SetResourceArray";
3623
3624    CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
3625
3626#ifdef _DEBUG
3627    for (size_t i = 0; i < Count; ++ i)
3628    {
3629        VH(ValidateTextureType(ppResources[i], pType->ObjectType, pFuncName));
3630    }
3631#endif
3632
3633    // Texture variables don't need to be dirtied.
3634    for (size_t i = 0; i < Count; ++ i)
3635    {
3636        SShaderResource *pResourceBlock = Data.pShaderResource + Offset + i;
3637        SAFE_ADDREF(ppResources[i]);
3638        SAFE_RELEASE(pResourceBlock->pShaderResource);
3639        pResourceBlock->pShaderResource = ppResources[i];
3640    }
3641
3642lExit:
3643    return hr;
3644}
3645
3646template<typename IBaseInterface>
3647_Use_decl_annotations_
3648HRESULT TShaderResourceVariable<IBaseInterface>::GetResourceArray(ID3D11ShaderResourceView **ppResources, uint32_t Offset, uint32_t Count)
3649{
3650    static LPCSTR pFuncName = "ID3DX11EffectShaderResourceVariable::GetResourceArray";
3651
3652    CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
3653
3654    for (size_t i = 0; i < Count; ++ i)
3655    {
3656        ppResources[i] = (Data.pShaderResource + Offset + i)->pShaderResource;
3657        SAFE_ADDREF(ppResources[i]);
3658    }
3659
3660lExit:
3661    return hr;
3662}
3663
3664//////////////////////////////////////////////////////////////////////////
3665// ID3DX11EffectUnorderedAccessViewVariable (TUnorderedAccessViewVariable implementation)
3666//////////////////////////////////////////////////////////////////////////
3667
3668template<typename IBaseInterface>
3669struct TUnorderedAccessViewVariable : public IBaseInterface
3670{
3671    STDMETHOD(SetUnorderedAccessView)(_In_ ID3D11UnorderedAccessView *pResource) override;
3672    STDMETHOD(GetUnorderedAccessView)(_Outptr_ ID3D11UnorderedAccessView **ppResource) override;
3673
3674    STDMETHOD(SetUnorderedAccessViewArray)(_In_reads_(Count) ID3D11UnorderedAccessView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
3675    STDMETHOD(GetUnorderedAccessViewArray)(_Out_writes_(Count) ID3D11UnorderedAccessView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
3676};
3677
3678static HRESULT ValidateTextureType(_In_ ID3D11UnorderedAccessView *pView, _In_ EObjectType ObjectType, _In_z_ LPCSTR pFuncName)
3679{
3680    if (nullptr != pView)
3681    {
3682        D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
3683        pView->GetDesc(&desc);
3684        switch (ObjectType)
3685        {
3686        case EOT_RWBuffer:
3687            if (desc.ViewDimension != D3D11_UAV_DIMENSION_BUFFER)
3688                break;
3689            if (desc.Buffer.Flags & D3D11_BUFFER_UAV_FLAG_RAW)
3690            {
3691                DPF(0, "%s: Resource type mismatch; %s expected, RWByteAddressBuffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
3692                return E_INVALIDARG;
3693            }
3694            else
3695            {
3696                ID3D11Buffer* pBuffer = nullptr;
3697                pView->GetResource( (ID3D11Resource**)&pBuffer );
3698                assert( pBuffer != nullptr );
3699                D3D11_BUFFER_DESC BufDesc;
3700                pBuffer->GetDesc( &BufDesc );
3701                SAFE_RELEASE( pBuffer );
3702                if( BufDesc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED )
3703                {
3704                    DPF(0, "%s: Resource type mismatch; %s expected, an RWStructuredBuffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
3705                    return E_INVALIDARG;
3706                }
3707                else
3708                {
3709                    return S_OK;
3710                }
3711            }
3712            break;
3713        case EOT_RWTexture1D:
3714        case EOT_RWTexture1DArray:
3715            if (desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1D ||
3716                desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY)
3717                return S_OK;
3718            break;
3719        case EOT_RWTexture2D:
3720        case EOT_RWTexture2DArray:
3721            if (desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2D ||
3722                desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY)
3723                return S_OK;
3724            break;
3725        case EOT_RWTexture3D:
3726            if (desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE3D)
3727                return S_OK;
3728            break;
3729        case EOT_RWByteAddressBuffer:
3730            if (desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER && (desc.Buffer.Flags & D3D11_BUFFER_UAV_FLAG_RAW))
3731                return S_OK;
3732            break;
3733        case EOT_RWStructuredBuffer:
3734            if (desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER)
3735            {
3736                ID3D11Buffer* pBuffer = nullptr;
3737                pView->GetResource( (ID3D11Resource**)&pBuffer );
3738                assert( pBuffer != nullptr );
3739                D3D11_BUFFER_DESC BufDesc;
3740                pBuffer->GetDesc( &BufDesc );
3741                SAFE_RELEASE( pBuffer );
3742                if( BufDesc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED )
3743                {
3744                    return S_OK;
3745                }
3746                else
3747                {
3748                    DPF(0, "%s: Resource type mismatch; %s expected, non-structured Buffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
3749                    return E_INVALIDARG;
3750                }
3751            }
3752            break;
3753        case EOT_RWStructuredBufferAlloc:
3754        case EOT_RWStructuredBufferConsume:
3755            if (desc.ViewDimension != D3D11_UAV_DIMENSION_BUFFER)
3756                break;
3757            if (desc.Buffer.Flags & D3D11_BUFFER_UAV_FLAG_COUNTER)
3758            {
3759                return S_OK;
3760            }
3761            else
3762            {
3763                DPF(0, "%s: Resource type mismatch; %s expected, non-Counter buffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
3764                return E_INVALIDARG;
3765            }
3766            break;
3767        case EOT_AppendStructuredBuffer:
3768        case EOT_ConsumeStructuredBuffer:
3769            if (desc.ViewDimension != D3D11_UAV_DIMENSION_BUFFER)
3770                break;
3771            if (desc.Buffer.Flags & D3D11_BUFFER_UAV_FLAG_APPEND)
3772            {
3773                return S_OK;
3774            }
3775            else
3776            {
3777                DPF(0, "%s: Resource type mismatch; %s expected, non-Append buffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
3778                return E_INVALIDARG;
3779            }
3780            break;
3781        default:
3782            assert(0); // internal error, should never get here
3783            return E_FAIL;
3784        }
3785
3786
3787        DPF(0, "%s: Resource type mismatch; %s expected, %s provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType), GetUAVDimensionNameFromEnum(desc.ViewDimension));
3788        return E_INVALIDARG;
3789    }
3790    return S_OK;
3791}
3792
3793template<typename IBaseInterface>
3794_Use_decl_annotations_
3795HRESULT TUnorderedAccessViewVariable<IBaseInterface>::SetUnorderedAccessView(ID3D11UnorderedAccessView *pResource)
3796{
3797    HRESULT hr = S_OK;
3798
3799#ifdef _DEBUG
3800    static LPCSTR pFuncName = "ID3DX11EffectUnorderedAccessViewVariable::SetUnorderedAccessView";
3801
3802    VH(ValidateTextureType(pResource, pType->ObjectType, pFuncName));
3803#endif
3804
3805    // UAV variables don't need to be dirtied.
3806    SAFE_ADDREF(pResource);
3807    SAFE_RELEASE(Data.pUnorderedAccessView->pUnorderedAccessView);
3808    Data.pUnorderedAccessView->pUnorderedAccessView = pResource;
3809
3810lExit:
3811    return hr;
3812}
3813
3814template<typename IBaseInterface>
3815_Use_decl_annotations_
3816HRESULT TUnorderedAccessViewVariable<IBaseInterface>::GetUnorderedAccessView(ID3D11UnorderedAccessView **ppResource)
3817{
3818    HRESULT hr = S_OK;
3819
3820#ifdef _DEBUG
3821    static LPCSTR pFuncName = "ID3DX11EffectUnorderedAccessViewVariable::GetUnorderedAccessView";
3822
3823    VERIFYPARAMETER(ppResource);
3824#endif
3825
3826    assert(Data.pUnorderedAccessView != 0 && Data.pUnorderedAccessView->pUnorderedAccessView != 0);
3827    _Analysis_assume_(Data.pUnorderedAccessView != 0 && Data.pUnorderedAccessView->pUnorderedAccessView != 0);
3828    *ppResource = Data.pUnorderedAccessView->pUnorderedAccessView;
3829    SAFE_ADDREF(*ppResource);
3830
3831lExit:
3832    return hr;
3833}
3834
3835template<typename IBaseInterface>
3836_Use_decl_annotations_
3837HRESULT TUnorderedAccessViewVariable<IBaseInterface>::SetUnorderedAccessViewArray(ID3D11UnorderedAccessView **ppResources, uint32_t Offset, uint32_t Count)
3838{
3839    static LPCSTR pFuncName = "ID3DX11EffectUnorderedAccessViewVariable::SetUnorderedAccessViewArray";
3840
3841    CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
3842
3843#ifdef _DEBUG
3844    for (size_t i = 0; i < Count; ++ i)
3845    {
3846        VH(ValidateTextureType(ppResources[i], pType->ObjectType, pFuncName));
3847    }
3848#endif
3849
3850    // Texture variables don't need to be dirtied.
3851    for (size_t i = 0; i < Count; ++ i)
3852    {
3853        SUnorderedAccessView *pResourceBlock = Data.pUnorderedAccessView + Offset + i;
3854        SAFE_ADDREF(ppResources[i]);
3855        SAFE_RELEASE(pResourceBlock->pUnorderedAccessView);
3856        pResourceBlock->pUnorderedAccessView = ppResources[i];
3857    }
3858
3859lExit:
3860    return hr;
3861}
3862
3863template<typename IBaseInterface>
3864_Use_decl_annotations_
3865HRESULT TUnorderedAccessViewVariable<IBaseInterface>::GetUnorderedAccessViewArray(ID3D11UnorderedAccessView **ppResources, uint32_t Offset, uint32_t Count)
3866{
3867    static LPCSTR pFuncName = "ID3DX11EffectUnorderedAccessViewVariable::GetUnorderedAccessViewArray";
3868
3869    CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
3870
3871    for (size_t i = 0; i < Count; ++ i)
3872    {
3873        ppResources[i] = (Data.pUnorderedAccessView + Offset + i)->pUnorderedAccessView;
3874        SAFE_ADDREF(ppResources[i]);
3875    }
3876
3877lExit:
3878    return hr;
3879}
3880
3881//////////////////////////////////////////////////////////////////////////
3882// ID3DX11EffectRenderTargetViewVariable (TRenderTargetViewVariable implementation)
3883//////////////////////////////////////////////////////////////////////////
3884
3885template<typename IBaseInterface>
3886struct TRenderTargetViewVariable : public IBaseInterface
3887{
3888    STDMETHOD(SetRenderTarget)(_In_ ID3D11RenderTargetView *pResource) override;
3889    STDMETHOD(GetRenderTarget)(_Outptr_ ID3D11RenderTargetView **ppResource) override;
3890
3891    STDMETHOD(SetRenderTargetArray)(_In_reads_(Count) ID3D11RenderTargetView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
3892    STDMETHOD(GetRenderTargetArray)(_Out_writes_(Count) ID3D11RenderTargetView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
3893};
3894
3895
3896template<typename IBaseInterface>
3897_Use_decl_annotations_
3898HRESULT TRenderTargetViewVariable<IBaseInterface>::SetRenderTarget(ID3D11RenderTargetView *pResource)
3899{
3900    HRESULT hr = S_OK;
3901
3902#ifdef _DEBUG
3903    static LPCSTR pFuncName = "ID3DX11EffectRenderTargetVariable::SetRenderTarget";
3904#endif
3905
3906    // Texture variables don't need to be dirtied.
3907    SAFE_ADDREF(pResource);
3908    SAFE_RELEASE(Data.pRenderTargetView->pRenderTargetView);
3909    Data.pRenderTargetView->pRenderTargetView = pResource;
3910
3911lExit:
3912    return hr;
3913}
3914
3915template<typename IBaseInterface>
3916_Use_decl_annotations_
3917HRESULT TRenderTargetViewVariable<IBaseInterface>::GetRenderTarget(ID3D11RenderTargetView **ppResource)
3918{
3919    HRESULT hr = S_OK;
3920
3921    assert(Data.pRenderTargetView->pRenderTargetView != 0);
3922    _Analysis_assume_(Data.pRenderTargetView->pRenderTargetView != 0);
3923    *ppResource = Data.pRenderTargetView->pRenderTargetView;
3924    SAFE_ADDREF(*ppResource);
3925
3926lExit:
3927    return hr;
3928}
3929
3930template<typename IBaseInterface>
3931_Use_decl_annotations_
3932HRESULT TRenderTargetViewVariable<IBaseInterface>::SetRenderTargetArray(ID3D11RenderTargetView **ppResources, uint32_t Offset, uint32_t Count)
3933{
3934    static LPCSTR pFuncName = "ID3DX11EffectRenderTargetVariable::SetRenderTargetArray";
3935
3936    CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
3937
3938    // Texture variables don't need to be dirtied.
3939    for (size_t i = 0; i < Count; ++ i)
3940    {
3941        SRenderTargetView *pResourceBlock = Data.pRenderTargetView + Offset + i;
3942        SAFE_ADDREF(ppResources[i]);
3943        SAFE_RELEASE(pResourceBlock->pRenderTargetView);
3944        pResourceBlock->pRenderTargetView = ppResources[i];
3945    }
3946
3947lExit:
3948    return hr;
3949}
3950
3951template<typename IBaseInterface>
3952_Use_decl_annotations_
3953HRESULT TRenderTargetViewVariable<IBaseInterface>::GetRenderTargetArray(ID3D11RenderTargetView **ppResources, uint32_t Offset, uint32_t Count)
3954{
3955    static LPCSTR pFuncName = "ID3DX11EffectRenderTargetVariable::GetRenderTargetArray";
3956
3957    CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
3958
3959    for (size_t i = 0; i < Count; ++ i)
3960    {
3961        ppResources[i] = (Data.pRenderTargetView + Offset + i)->pRenderTargetView;
3962        SAFE_ADDREF(ppResources[i]);
3963    }
3964
3965lExit:
3966    return hr;
3967}
3968
3969//////////////////////////////////////////////////////////////////////////
3970// ID3DX11EffectDepthStencilViewVariable (TDepthStencilViewVariable implementation)
3971//////////////////////////////////////////////////////////////////////////
3972
3973template<typename IBaseInterface>
3974struct TDepthStencilViewVariable : public IBaseInterface
3975{
3976    STDMETHOD(SetDepthStencil)(_In_ ID3D11DepthStencilView *pResource)  override;
3977    STDMETHOD(GetDepthStencil)(_Outptr_ ID3D11DepthStencilView **ppResource)  override;
3978
3979    STDMETHOD(SetDepthStencilArray)(_In_reads_(Count) ID3D11DepthStencilView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count)  override;
3980    STDMETHOD(GetDepthStencilArray)(_Out_writes_(Count) ID3D11DepthStencilView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count)  override;
3981};
3982
3983
3984template<typename IBaseInterface>
3985_Use_decl_annotations_
3986HRESULT TDepthStencilViewVariable<IBaseInterface>::SetDepthStencil(ID3D11DepthStencilView *pResource)
3987{
3988    HRESULT hr = S_OK;
3989
3990#ifdef _DEBUG
3991    static LPCSTR pFuncName = "ID3D11DepthStencilViewVariable::SetDepthStencil";
3992
3993#endif
3994
3995    // Texture variables don't need to be dirtied.
3996    SAFE_ADDREF(pResource);
3997    SAFE_RELEASE(Data.pDepthStencilView->pDepthStencilView);
3998    Data.pDepthStencilView->pDepthStencilView = pResource;
3999
4000lExit:
4001    return hr;
4002}
4003
4004template<typename IBaseInterface>
4005_Use_decl_annotations_
4006HRESULT TDepthStencilViewVariable<IBaseInterface>::GetDepthStencil(ID3D11DepthStencilView **ppResource)
4007{
4008    HRESULT hr = S_OK;
4009
4010#ifdef _DEBUG
4011    static LPCSTR pFuncName = "ID3D11DepthStencilViewVariable::GetDepthStencil";
4012
4013    VERIFYPARAMETER(ppResource);
4014#endif
4015
4016    assert(Data.pDepthStencilView->pDepthStencilView != 0);
4017    _Analysis_assume_(Data.pDepthStencilView->pDepthStencilView != 0);
4018    *ppResource = Data.pDepthStencilView->pDepthStencilView;
4019    SAFE_ADDREF(*ppResource);
4020
4021lExit:
4022    return hr;
4023}
4024
4025template<typename IBaseInterface>
4026_Use_decl_annotations_
4027HRESULT TDepthStencilViewVariable<IBaseInterface>::SetDepthStencilArray(ID3D11DepthStencilView **ppResources, uint32_t Offset, uint32_t Count)
4028{
4029    static LPCSTR pFuncName = "ID3D11DepthStencilViewVariable::SetDepthStencilArray";
4030
4031    CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
4032
4033    // Texture variables don't need to be dirtied.
4034    for (size_t i = 0; i < Count; ++ i)
4035    {
4036        SDepthStencilView *pResourceBlock = Data.pDepthStencilView + Offset + i;
4037        SAFE_ADDREF(ppResources[i]);
4038        SAFE_RELEASE(pResourceBlock->pDepthStencilView);
4039        pResourceBlock->pDepthStencilView = ppResources[i];
4040    }
4041
4042lExit:
4043    return hr;
4044}
4045
4046template<typename IBaseInterface>
4047_Use_decl_annotations_
4048HRESULT TDepthStencilViewVariable<IBaseInterface>::GetDepthStencilArray(ID3D11DepthStencilView **ppResources, uint32_t Offset, uint32_t Count)
4049{
4050    static LPCSTR pFuncName = "ID3D11DepthStencilViewVariable::GetDepthStencilArray";
4051
4052    CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
4053
4054    for (size_t i = 0; i < Count; ++ i)
4055    {
4056        ppResources[i] = (Data.pDepthStencilView + Offset + i)->pDepthStencilView;
4057        SAFE_ADDREF(ppResources[i]);
4058    }
4059
4060lExit:
4061    return hr;
4062}
4063
4064////////////////////////////////////////////////////////////////////////////////
4065// ID3DX11EffectShaderVariable (TShaderVariable implementation)
4066////////////////////////////////////////////////////////////////////////////////
4067
4068template<typename IBaseInterface>
4069struct TShaderVariable : public IBaseInterface
4070{
4071    STDMETHOD(GetShaderDesc)(_In_ uint32_t ShaderIndex, _Out_ D3DX11_EFFECT_SHADER_DESC *pDesc)  override;
4072
4073    STDMETHOD(GetVertexShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11VertexShader **ppVS)  override;
4074    STDMETHOD(GetGeometryShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11GeometryShader **ppGS)  override;
4075    STDMETHOD(GetPixelShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11PixelShader **ppPS)  override;
4076    STDMETHOD(GetHullShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11HullShader **ppHS)  override;
4077    STDMETHOD(GetDomainShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11DomainShader **ppDS)  override;
4078    STDMETHOD(GetComputeShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11ComputeShader **ppCS)  override;
4079
4080    STDMETHOD(GetInputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc)  override;
4081    STDMETHOD(GetOutputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc)  override;
4082    STDMETHOD(GetPatchConstantSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc)  override;
4083
4084    STDMETHOD_(bool, IsValid)();
4085};
4086
4087template<typename IBaseInterface>
4088_Use_decl_annotations_
4089HRESULT TShaderVariable<IBaseInterface>::GetShaderDesc(uint32_t ShaderIndex, D3DX11_EFFECT_SHADER_DESC *pDesc)
4090{
4091    static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetShaderDesc";
4092
4093    CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, pDesc);
4094
4095    hr = Data.pShader[ShaderIndex].GetShaderDesc(pDesc, false);
4096
4097lExit:
4098    return hr;
4099}
4100
4101template<typename IBaseInterface>
4102_Use_decl_annotations_
4103HRESULT TShaderVariable<IBaseInterface>::GetVertexShader(uint32_t ShaderIndex, ID3D11VertexShader **ppVS)
4104{
4105    static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetVertexShader";
4106
4107    CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, ppVS);
4108
4109    VH( Data.pShader[ShaderIndex].GetVertexShader(ppVS) );
4110
4111lExit:
4112    return hr;
4113}
4114
4115template<typename IBaseInterface>
4116_Use_decl_annotations_
4117HRESULT TShaderVariable<IBaseInterface>::GetGeometryShader(uint32_t ShaderIndex, ID3D11GeometryShader **ppGS)
4118{
4119    static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetGeometryShader";
4120
4121    CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, ppGS);
4122
4123    VH( Data.pShader[ShaderIndex].GetGeometryShader(ppGS) );
4124
4125lExit:
4126    return hr;
4127}
4128
4129template<typename IBaseInterface>
4130_Use_decl_annotations_
4131HRESULT TShaderVariable<IBaseInterface>::GetPixelShader(uint32_t ShaderIndex, ID3D11PixelShader **ppPS)
4132{
4133    static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetPixelShader";
4134
4135    CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, ppPS);
4136
4137    VH( Data.pShader[ShaderIndex].GetPixelShader(ppPS) );
4138
4139lExit:
4140    return hr;
4141}
4142
4143template<typename IBaseInterface>
4144_Use_decl_annotations_
4145HRESULT TShaderVariable<IBaseInterface>::GetHullShader(uint32_t ShaderIndex, ID3D11HullShader **ppHS)
4146{
4147    static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetHullShader";
4148
4149    CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, ppHS);
4150
4151    VH( Data.pShader[ShaderIndex].GetHullShader(ppHS) );
4152
4153lExit:
4154    return hr;
4155}
4156
4157template<typename IBaseInterface>
4158_Use_decl_annotations_
4159HRESULT TShaderVariable<IBaseInterface>::GetDomainShader(uint32_t ShaderIndex, ID3D11DomainShader **ppDS)
4160{
4161    static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetDomainShader";
4162
4163    CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, ppDS);
4164
4165    VH( Data.pShader[ShaderIndex].GetDomainShader(ppDS) );
4166
4167lExit:
4168    return hr;
4169}
4170
4171template<typename IBaseInterface>
4172_Use_decl_annotations_
4173HRESULT TShaderVariable<IBaseInterface>::GetComputeShader(uint32_t ShaderIndex, ID3D11ComputeShader **ppCS)
4174{
4175    static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetComputeShader";
4176
4177    CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, ppCS);
4178
4179    VH( Data.pShader[ShaderIndex].GetComputeShader(ppCS) );
4180
4181lExit:
4182    return hr;
4183}
4184
4185template<typename IBaseInterface>
4186_Use_decl_annotations_
4187HRESULT TShaderVariable<IBaseInterface>::GetInputSignatureElementDesc(uint32_t ShaderIndex, uint32_t Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
4188{
4189    static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetInputSignatureElementDesc";
4190
4191    CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, pDesc);
4192
4193    VH( Data.pShader[ShaderIndex].GetSignatureElementDesc(SShaderBlock::ST_Input, Element, pDesc) );
4194
4195lExit:
4196    return hr;
4197}
4198
4199template<typename IBaseInterface>
4200_Use_decl_annotations_
4201HRESULT TShaderVariable<IBaseInterface>::GetOutputSignatureElementDesc(uint32_t ShaderIndex, uint32_t Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
4202{
4203    static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetOutputSignatureElementDesc";
4204
4205    CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, pDesc);
4206
4207    VH( Data.pShader[ShaderIndex].GetSignatureElementDesc(SShaderBlock::ST_Output, Element, pDesc) );
4208
4209lExit:
4210    return hr;
4211}
4212
4213template<typename IBaseInterface>
4214_Use_decl_annotations_
4215HRESULT TShaderVariable<IBaseInterface>::GetPatchConstantSignatureElementDesc(uint32_t ShaderIndex, uint32_t Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
4216{
4217    static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetPatchConstantSignatureElementDesc";
4218
4219    CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, pDesc);
4220
4221    VH( Data.pShader[ShaderIndex].GetSignatureElementDesc(SShaderBlock::ST_PatchConstant, Element, pDesc) );
4222
4223lExit:
4224    return hr;
4225}
4226
4227template<typename IBaseInterface>
4228bool TShaderVariable<IBaseInterface>::IsValid()
4229{
4230    uint32_t numElements = IsArray()? pType->Elements : 1;
4231    bool valid = true;
4232    while( numElements > 0 && ( valid = Data.pShader[ numElements-1 ].IsValid ) )
4233        numElements--;
4234    return valid;
4235}
4236
4237////////////////////////////////////////////////////////////////////////////////
4238// ID3DX11EffectBlendVariable (TBlendVariable implementation)
4239////////////////////////////////////////////////////////////////////////////////
4240
4241template<typename IBaseInterface>
4242struct TBlendVariable : public IBaseInterface
4243{
4244public:
4245    STDMETHOD(GetBlendState)(_In_ uint32_t Index, _Outptr_ ID3D11BlendState **ppState)  override;
4246    STDMETHOD(SetBlendState)(_In_ uint32_t Index, _In_ ID3D11BlendState *pState)  override;
4247    STDMETHOD(UndoSetBlendState)(_In_ uint32_t Index)  override;
4248    STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_BLEND_DESC *pDesc)  override;
4249    STDMETHOD_(bool, IsValid)()  override;
4250};
4251
4252template<typename IBaseInterface>
4253_Use_decl_annotations_
4254HRESULT TBlendVariable<IBaseInterface>::GetBlendState(uint32_t Index, ID3D11BlendState **ppState)
4255{
4256    static LPCSTR pFuncName = "ID3DX11EffectBlendVariable::GetBlendState";
4257
4258    CHECK_OBJECT_SCALAR_BOUNDS(Index, ppState);
4259
4260    assert(Data.pBlend[Index].pBlendObject != 0);
4261    _Analysis_assume_(Data.pBlend[Index].pBlendObject != 0);
4262    *ppState = Data.pBlend[Index].pBlendObject;
4263    SAFE_ADDREF(*ppState);
4264
4265lExit:
4266    return hr;
4267}
4268
4269template<typename IBaseInterface>
4270_Use_decl_annotations_
4271HRESULT TBlendVariable<IBaseInterface>::SetBlendState(uint32_t Index, ID3D11BlendState *pState)
4272{
4273    static LPCSTR pFuncName = "ID3DX11EffectBlendState::SetBlendState";
4274
4275    CHECK_SCALAR_BOUNDS(Index);
4276
4277    if( !Data.pBlend[Index].IsUserManaged )
4278    {
4279        // Save original state object in case we UndoSet
4280        assert( pMemberData[Index].Type == MDT_BlendState );
4281        VB( pMemberData[Index].Data.pD3DEffectsManagedBlendState == nullptr );
4282        pMemberData[Index].Data.pD3DEffectsManagedBlendState = Data.pBlend[Index].pBlendObject;
4283        Data.pBlend[Index].pBlendObject = nullptr;
4284        Data.pBlend[Index].IsUserManaged = true;
4285    }
4286
4287    SAFE_ADDREF( pState );
4288    SAFE_RELEASE( Data.pBlend[Index].pBlendObject );
4289    Data.pBlend[Index].pBlendObject = pState;
4290    Data.pBlend[Index].IsValid = true;
4291lExit:
4292    return hr;
4293}
4294
4295template<typename IBaseInterface>
4296_Use_decl_annotations_
4297HRESULT TBlendVariable<IBaseInterface>::UndoSetBlendState(uint32_t Index)
4298{
4299    static LPCSTR pFuncName = "ID3DX11EffectBlendState::UndoSetBlendState";
4300
4301    CHECK_SCALAR_BOUNDS(Index);
4302
4303    if( !Data.pBlend[Index].IsUserManaged )
4304    {
4305        return S_FALSE;
4306    }
4307
4308    // Revert to original state object
4309    SAFE_RELEASE( Data.pBlend[Index].pBlendObject );
4310    Data.pBlend[Index].pBlendObject = pMemberData[Index].Data.pD3DEffectsManagedBlendState;
4311    pMemberData[Index].Data.pD3DEffectsManagedBlendState = nullptr;
4312    Data.pBlend[Index].IsUserManaged = false;
4313
4314lExit:
4315    return hr;
4316}
4317
4318template<typename IBaseInterface>
4319_Use_decl_annotations_
4320HRESULT TBlendVariable<IBaseInterface>::GetBackingStore(uint32_t Index, D3D11_BLEND_DESC *pBlendDesc)
4321{
4322    static LPCSTR pFuncName = "ID3DX11EffectBlendVariable::GetBackingStore";
4323
4324    CHECK_OBJECT_SCALAR_BOUNDS(Index, pBlendDesc);
4325
4326    if( Data.pBlend[Index].IsUserManaged )
4327    {
4328        if( Data.pBlend[Index].pBlendObject )
4329        {
4330            Data.pBlend[Index].pBlendObject->GetDesc( pBlendDesc );
4331        }
4332        else
4333        {
4334            *pBlendDesc = CD3D11_BLEND_DESC( D3D11_DEFAULT );
4335        }
4336    }
4337    else
4338    {
4339        SBlendBlock *pBlock = Data.pBlend + Index;
4340        if (pBlock->ApplyAssignments(GetTopLevelEntity()->pEffect))
4341        {
4342            pBlock->pAssignments[0].LastRecomputedTime = 0; // Force a recreate of this block the next time ApplyRenderStateBlock is called
4343        }
4344
4345        memcpy( pBlendDesc, &pBlock->BackingStore, sizeof(D3D11_BLEND_DESC) );
4346    }
4347
4348lExit:
4349    return hr;
4350}
4351
4352template<typename IBaseInterface>
4353bool TBlendVariable<IBaseInterface>::IsValid()
4354{
4355    uint32_t numElements = IsArray()? pType->Elements : 1;
4356    bool valid = true;
4357    while( numElements > 0 && ( valid = Data.pBlend[ numElements-1 ].IsValid ) )
4358        numElements--;
4359    return valid;
4360}
4361
4362
4363////////////////////////////////////////////////////////////////////////////////
4364// ID3DX11EffectDepthStencilVariable (TDepthStencilVariable implementation)
4365////////////////////////////////////////////////////////////////////////////////
4366
4367template<typename IBaseInterface>
4368struct TDepthStencilVariable : public IBaseInterface
4369{
4370public:
4371    STDMETHOD(GetDepthStencilState)(_In_ uint32_t Index, _Outptr_ ID3D11DepthStencilState **ppState)  override;
4372    STDMETHOD(SetDepthStencilState)(_In_ uint32_t Index, _In_ ID3D11DepthStencilState *pState)  override;
4373    STDMETHOD(UndoSetDepthStencilState)(_In_ uint32_t Index)  override;
4374    STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_DEPTH_STENCIL_DESC *pDesc) override;
4375    STDMETHOD_(bool, IsValid)()  override;
4376};
4377
4378template<typename IBaseInterface>
4379_Use_decl_annotations_
4380HRESULT TDepthStencilVariable<IBaseInterface>::GetDepthStencilState(uint32_t Index, ID3D11DepthStencilState **ppState)
4381{
4382    static LPCSTR pFuncName = "ID3DX11EffectDepthStencilVariable::GetDepthStencilState";
4383
4384    CHECK_OBJECT_SCALAR_BOUNDS(Index, ppState);
4385
4386    assert(Data.pDepthStencil[Index].pDSObject != 0);
4387    _Analysis_assume_(Data.pDepthStencil[Index].pDSObject != 0);
4388    *ppState = Data.pDepthStencil[Index].pDSObject;
4389    SAFE_ADDREF(*ppState);
4390
4391lExit:
4392    return hr;
4393}
4394
4395template<typename IBaseInterface>
4396_Use_decl_annotations_
4397HRESULT TDepthStencilVariable<IBaseInterface>::SetDepthStencilState(uint32_t Index, ID3D11DepthStencilState *pState)
4398{
4399    static LPCSTR pFuncName = "ID3DX11EffectDepthStencilState::SetDepthStencilState";
4400
4401    CHECK_SCALAR_BOUNDS(Index);
4402
4403    if( !Data.pDepthStencil[Index].IsUserManaged )
4404    {
4405        // Save original state object in case we UndoSet
4406        assert( pMemberData[Index].Type == MDT_DepthStencilState );
4407        VB( pMemberData[Index].Data.pD3DEffectsManagedDepthStencilState == nullptr );
4408        pMemberData[Index].Data.pD3DEffectsManagedDepthStencilState = Data.pDepthStencil[Index].pDSObject;
4409        Data.pDepthStencil[Index].pDSObject = nullptr;
4410        Data.pDepthStencil[Index].IsUserManaged = true;
4411    }
4412
4413    SAFE_ADDREF( pState );
4414    SAFE_RELEASE( Data.pDepthStencil[Index].pDSObject );
4415    Data.pDepthStencil[Index].pDSObject = pState;
4416    Data.pDepthStencil[Index].IsValid = true;
4417lExit:
4418    return hr;
4419}
4420
4421template<typename IBaseInterface>
4422HRESULT TDepthStencilVariable<IBaseInterface>::UndoSetDepthStencilState(_In_ uint32_t Index)
4423{
4424    static LPCSTR pFuncName = "ID3DX11EffectDepthStencilState::UndoSetDepthStencilState";
4425
4426    CHECK_SCALAR_BOUNDS(Index);
4427
4428    if( !Data.pDepthStencil[Index].IsUserManaged )
4429    {
4430        return S_FALSE;
4431    }
4432
4433    // Revert to original state object
4434    SAFE_RELEASE( Data.pDepthStencil[Index].pDSObject );
4435    Data.pDepthStencil[Index].pDSObject = pMemberData[Index].Data.pD3DEffectsManagedDepthStencilState;
4436    pMemberData[Index].Data.pD3DEffectsManagedDepthStencilState = nullptr;
4437    Data.pDepthStencil[Index].IsUserManaged = false;
4438
4439lExit:
4440    return hr;
4441}
4442
4443template<typename IBaseInterface>
4444_Use_decl_annotations_
4445HRESULT TDepthStencilVariable<IBaseInterface>::GetBackingStore(uint32_t Index, D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc)
4446{
4447    static LPCSTR pFuncName = "ID3DX11EffectDepthStencilVariable::GetBackingStore";
4448
4449    CHECK_OBJECT_SCALAR_BOUNDS(Index, pDepthStencilDesc);
4450
4451    if( Data.pDepthStencil[Index].IsUserManaged )
4452    {
4453        if( Data.pDepthStencil[Index].pDSObject )
4454        {
4455            Data.pDepthStencil[Index].pDSObject->GetDesc( pDepthStencilDesc );
4456        }
4457        else
4458        {
4459            *pDepthStencilDesc = CD3D11_DEPTH_STENCIL_DESC( D3D11_DEFAULT );
4460        }
4461    }
4462    else
4463    {
4464        SDepthStencilBlock *pBlock = Data.pDepthStencil + Index;
4465        if (pBlock->ApplyAssignments(GetTopLevelEntity()->pEffect))
4466        {
4467            pBlock->pAssignments[0].LastRecomputedTime = 0; // Force a recreate of this block the next time ApplyRenderStateBlock is called
4468        }
4469
4470        memcpy(pDepthStencilDesc, &pBlock->BackingStore, sizeof(D3D11_DEPTH_STENCIL_DESC));
4471    }
4472
4473lExit:
4474    return hr;
4475}
4476
4477template<typename IBaseInterface>
4478bool TDepthStencilVariable<IBaseInterface>::IsValid()
4479{
4480    uint32_t numElements = IsArray()? pType->Elements : 1;
4481    bool valid = true;
4482    while( numElements > 0 && ( valid = Data.pDepthStencil[ numElements-1 ].IsValid ) )
4483        numElements--;
4484    return valid;
4485}
4486
4487////////////////////////////////////////////////////////////////////////////////
4488// ID3DX11EffectRasterizerVariable (TRasterizerVariable implementation)
4489////////////////////////////////////////////////////////////////////////////////
4490
4491template<typename IBaseInterface>
4492struct TRasterizerVariable : public IBaseInterface
4493{
4494public:
4495
4496    STDMETHOD(GetRasterizerState)(_In_ uint32_t Index, _Outptr_ ID3D11RasterizerState **ppState)  override;
4497    STDMETHOD(SetRasterizerState)(_In_ uint32_t Index, _In_ ID3D11RasterizerState *pState)  override;
4498    STDMETHOD(UndoSetRasterizerState)(_In_ uint32_t Index)  override;
4499    STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_RASTERIZER_DESC *pDesc)  override;
4500    STDMETHOD_(bool, IsValid)()  override;
4501};
4502
4503template<typename IBaseInterface>
4504_Use_decl_annotations_
4505HRESULT TRasterizerVariable<IBaseInterface>::GetRasterizerState(uint32_t Index, ID3D11RasterizerState **ppState)
4506{
4507    static LPCSTR pFuncName = "ID3DX11EffectRasterizerVariable::GetRasterizerState";
4508
4509    CHECK_OBJECT_SCALAR_BOUNDS(Index, ppState);
4510
4511    assert(Data.pRasterizer[Index].pRasterizerObject != 0);
4512    _Analysis_assume_(Data.pRasterizer[Index].pRasterizerObject != 0);
4513    *ppState = Data.pRasterizer[Index].pRasterizerObject;
4514    SAFE_ADDREF(*ppState);
4515
4516lExit:
4517    return hr;
4518}
4519
4520template<typename IBaseInterface>
4521_Use_decl_annotations_
4522HRESULT TRasterizerVariable<IBaseInterface>::SetRasterizerState(uint32_t Index, ID3D11RasterizerState *pState)
4523{
4524    static LPCSTR pFuncName = "ID3DX11EffectRasterizerState::SetRasterizerState";
4525
4526    CHECK_SCALAR_BOUNDS(Index);
4527
4528    if( !Data.pRasterizer[Index].IsUserManaged )
4529    {
4530        // Save original state object in case we UndoSet
4531        assert( pMemberData[Index].Type == MDT_RasterizerState );
4532        VB( pMemberData[Index].Data.pD3DEffectsManagedRasterizerState == nullptr );
4533        pMemberData[Index].Data.pD3DEffectsManagedRasterizerState = Data.pRasterizer[Index].pRasterizerObject;
4534        Data.pRasterizer[Index].pRasterizerObject = nullptr;
4535        Data.pRasterizer[Index].IsUserManaged = true;
4536    }
4537
4538    SAFE_ADDREF( pState );
4539    SAFE_RELEASE( Data.pRasterizer[Index].pRasterizerObject );
4540    Data.pRasterizer[Index].pRasterizerObject = pState;
4541    Data.pRasterizer[Index].IsValid = true;
4542lExit:
4543    return hr;
4544}
4545
4546template<typename IBaseInterface>
4547_Use_decl_annotations_
4548HRESULT TRasterizerVariable<IBaseInterface>::UndoSetRasterizerState(uint32_t Index)
4549{
4550    static LPCSTR pFuncName = "ID3DX11EffectRasterizerState::UndoSetRasterizerState";
4551
4552    CHECK_SCALAR_BOUNDS(Index);
4553
4554    if( !Data.pRasterizer[Index].IsUserManaged )
4555    {
4556        return S_FALSE;
4557    }
4558
4559    // Revert to original state object
4560    SAFE_RELEASE( Data.pRasterizer[Index].pRasterizerObject );
4561    Data.pRasterizer[Index].pRasterizerObject = pMemberData[Index].Data.pD3DEffectsManagedRasterizerState;
4562    pMemberData[Index].Data.pD3DEffectsManagedRasterizerState = nullptr;
4563    Data.pRasterizer[Index].IsUserManaged = false;
4564
4565lExit:
4566    return hr;
4567}
4568
4569template<typename IBaseInterface>
4570_Use_decl_annotations_
4571HRESULT TRasterizerVariable<IBaseInterface>::GetBackingStore(uint32_t Index, D3D11_RASTERIZER_DESC *pRasterizerDesc)
4572{
4573    static LPCSTR pFuncName = "ID3DX11EffectRasterizerVariable::GetBackingStore";
4574
4575    CHECK_OBJECT_SCALAR_BOUNDS(Index, pRasterizerDesc);
4576
4577    if( Data.pRasterizer[Index].IsUserManaged )
4578    {
4579        if( Data.pRasterizer[Index].pRasterizerObject )
4580        {
4581            Data.pRasterizer[Index].pRasterizerObject->GetDesc( pRasterizerDesc );
4582        }
4583        else
4584        {
4585            *pRasterizerDesc = CD3D11_RASTERIZER_DESC( D3D11_DEFAULT );
4586        }
4587    }
4588    else
4589    {
4590        SRasterizerBlock *pBlock = Data.pRasterizer + Index;
4591        if (pBlock->ApplyAssignments(GetTopLevelEntity()->pEffect))
4592        {
4593            pBlock->pAssignments[0].LastRecomputedTime = 0; // Force a recreate of this block the next time ApplyRenderStateBlock is called
4594        }
4595
4596        memcpy(pRasterizerDesc, &pBlock->BackingStore, sizeof(D3D11_RASTERIZER_DESC));
4597    }
4598
4599lExit:
4600    return hr;
4601}
4602
4603template<typename IBaseInterface>
4604bool TRasterizerVariable<IBaseInterface>::IsValid()
4605{
4606    uint32_t numElements = IsArray()? pType->Elements : 1;
4607    bool valid = true;
4608    while( numElements > 0 && ( valid = Data.pRasterizer[ numElements-1 ].IsValid ) )
4609        numElements--;
4610    return valid;
4611}
4612
4613////////////////////////////////////////////////////////////////////////////////
4614// ID3DX11EffectSamplerVariable (TSamplerVariable implementation)
4615////////////////////////////////////////////////////////////////////////////////
4616
4617template<typename IBaseInterface>
4618struct TSamplerVariable : public IBaseInterface
4619{
4620public:
4621
4622    STDMETHOD(GetSampler)(_In_ uint32_t Index, _Outptr_ ID3D11SamplerState **ppSampler) override;
4623    STDMETHOD(SetSampler)(_In_ uint32_t Index, _In_ ID3D11SamplerState *pSampler) override;
4624    STDMETHOD(UndoSetSampler)(_In_ uint32_t Index)  override;
4625    STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_SAMPLER_DESC *pDesc)  override;
4626};
4627
4628template<typename IBaseInterface>
4629_Use_decl_annotations_
4630HRESULT TSamplerVariable<IBaseInterface>::GetSampler(uint32_t Index, ID3D11SamplerState **ppSampler)
4631{
4632    static LPCSTR pFuncName = "ID3DX11EffectSamplerVariable::GetSampler";
4633
4634    CHECK_OBJECT_SCALAR_BOUNDS(Index, ppSampler);
4635
4636    _Analysis_assume_( Data.pSampler[Index].pD3DObject != 0 );
4637    *ppSampler = Data.pSampler[Index].pD3DObject;
4638    SAFE_ADDREF(*ppSampler);
4639
4640lExit:
4641    return hr;
4642}
4643
4644template<typename IBaseInterface>
4645_Use_decl_annotations_
4646HRESULT TSamplerVariable<IBaseInterface>::SetSampler(uint32_t Index, ID3D11SamplerState *pSampler)
4647{
4648    static LPCSTR pFuncName = "ID3DX11EffectSamplerState::SetSampler";
4649
4650    CHECK_SCALAR_BOUNDS(Index);
4651
4652    // Replace all references to the old shader block with this one
4653    GetEffect()->ReplaceSamplerReference(&Data.pSampler[Index], pSampler);
4654
4655    if( !Data.pSampler[Index].IsUserManaged )
4656    {
4657        // Save original state object in case we UndoSet
4658        assert( pMemberData[Index].Type == MDT_SamplerState );
4659        VB( pMemberData[Index].Data.pD3DEffectsManagedSamplerState == nullptr );
4660        pMemberData[Index].Data.pD3DEffectsManagedSamplerState = Data.pSampler[Index].pD3DObject;
4661        Data.pSampler[Index].pD3DObject = nullptr;
4662        Data.pSampler[Index].IsUserManaged = true;
4663    }
4664
4665    SAFE_ADDREF( pSampler );
4666    SAFE_RELEASE( Data.pSampler[Index].pD3DObject );
4667    Data.pSampler[Index].pD3DObject = pSampler;
4668lExit:
4669    return hr;
4670}
4671
4672template<typename IBaseInterface>
4673HRESULT TSamplerVariable<IBaseInterface>::UndoSetSampler(_In_ uint32_t Index)
4674{
4675    static LPCSTR pFuncName = "ID3DX11EffectSamplerState::UndoSetSampler";
4676
4677    CHECK_SCALAR_BOUNDS(Index);
4678
4679    if( !Data.pSampler[Index].IsUserManaged )
4680    {
4681        return S_FALSE;
4682    }
4683
4684    // Replace all references to the old shader block with this one
4685    GetEffect()->ReplaceSamplerReference(&Data.pSampler[Index], pMemberData[Index].Data.pD3DEffectsManagedSamplerState);
4686
4687    // Revert to original state object
4688    SAFE_RELEASE( Data.pSampler[Index].pD3DObject );
4689    Data.pSampler[Index].pD3DObject = pMemberData[Index].Data.pD3DEffectsManagedSamplerState;
4690    pMemberData[Index].Data.pD3DEffectsManagedSamplerState = nullptr;
4691    Data.pSampler[Index].IsUserManaged = false;
4692
4693lExit:
4694    return hr;
4695}
4696
4697template<typename IBaseInterface>
4698_Use_decl_annotations_
4699HRESULT TSamplerVariable<IBaseInterface>::GetBackingStore(uint32_t Index, D3D11_SAMPLER_DESC *pDesc)
4700{
4701    static LPCSTR pFuncName = "ID3DX11EffectSamplerVariable::GetBackingStore";
4702
4703    CHECK_OBJECT_SCALAR_BOUNDS(Index, pDesc);
4704
4705    if( Data.pSampler[Index].IsUserManaged )
4706    {
4707        if( Data.pSampler[Index].pD3DObject )
4708        {
4709            Data.pSampler[Index].pD3DObject->GetDesc( pDesc );
4710        }
4711        else
4712        {
4713            *pDesc = CD3D11_SAMPLER_DESC( D3D11_DEFAULT );
4714        }
4715    }
4716    else
4717    {
4718        SSamplerBlock *pBlock = Data.pSampler + Index;
4719        if (pBlock->ApplyAssignments(GetTopLevelEntity()->pEffect))
4720        {
4721            pBlock->pAssignments[0].LastRecomputedTime = 0; // Force a recreate of this block the next time ApplyRenderStateBlock is called
4722        }
4723
4724        memcpy(pDesc, &pBlock->BackingStore.SamplerDesc, sizeof(D3D11_SAMPLER_DESC));
4725    }
4726
4727lExit:
4728    return hr;
4729}
4730
4731////////////////////////////////////////////////////////////////////////////////
4732// TUncastableVariable
4733////////////////////////////////////////////////////////////////////////////////
4734
4735template<typename IBaseInterface>
4736struct TUncastableVariable : public IBaseInterface
4737{
4738    STDMETHOD_(ID3DX11EffectScalarVariable*, AsScalar)() override;
4739    STDMETHOD_(ID3DX11EffectVectorVariable*, AsVector)() override;
4740    STDMETHOD_(ID3DX11EffectMatrixVariable*, AsMatrix)() override;
4741    STDMETHOD_(ID3DX11EffectStringVariable*, AsString)() override;
4742    STDMETHOD_(ID3DX11EffectClassInstanceVariable*, AsClassInstance)() override;
4743    STDMETHOD_(ID3DX11EffectInterfaceVariable*, AsInterface)() override;
4744    STDMETHOD_(ID3DX11EffectShaderResourceVariable*, AsShaderResource)() override;
4745    STDMETHOD_(ID3DX11EffectUnorderedAccessViewVariable*, AsUnorderedAccessView)() override;
4746    STDMETHOD_(ID3DX11EffectRenderTargetViewVariable*, AsRenderTargetView)() override;
4747    STDMETHOD_(ID3DX11EffectDepthStencilViewVariable*, AsDepthStencilView)() override;
4748    STDMETHOD_(ID3DX11EffectConstantBuffer*, AsConstantBuffer)() override;
4749    STDMETHOD_(ID3DX11EffectShaderVariable*, AsShader)() override;
4750    STDMETHOD_(ID3DX11EffectBlendVariable*, AsBlend)() override;
4751    STDMETHOD_(ID3DX11EffectDepthStencilVariable*, AsDepthStencil)() override;
4752    STDMETHOD_(ID3DX11EffectRasterizerVariable*, AsRasterizer)() override;
4753    STDMETHOD_(ID3DX11EffectSamplerVariable*, AsSampler)() override;
4754};
4755
4756template<typename IBaseInterface>
4757ID3DX11EffectScalarVariable * TUncastableVariable<IBaseInterface>::AsScalar()
4758{
4759    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsScalar";
4760    DPF(0, "%s: Invalid typecast", pFuncName);
4761    return &g_InvalidScalarVariable;
4762}
4763
4764template<typename IBaseInterface>
4765ID3DX11EffectVectorVariable * TUncastableVariable<IBaseInterface>::AsVector()
4766{
4767    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsVector";
4768    DPF(0, "%s: Invalid typecast", pFuncName);
4769    return &g_InvalidVectorVariable;
4770}
4771
4772template<typename IBaseInterface>
4773ID3DX11EffectMatrixVariable * TUncastableVariable<IBaseInterface>::AsMatrix()
4774{
4775    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsMatrix";
4776    DPF(0, "%s: Invalid typecast", pFuncName);
4777    return &g_InvalidMatrixVariable;
4778}
4779
4780template<typename IBaseInterface>
4781ID3DX11EffectStringVariable * TUncastableVariable<IBaseInterface>::AsString()
4782{
4783    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsString";
4784    DPF(0, "%s: Invalid typecast", pFuncName);
4785    return &g_InvalidStringVariable;
4786}
4787
4788template<typename IBaseClassInstance>
4789ID3DX11EffectClassInstanceVariable * TUncastableVariable<IBaseClassInstance>::AsClassInstance()
4790{
4791    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsClassInstance";
4792    DPF(0, "%s: Invalid typecast", pFuncName);
4793    return &g_InvalidClassInstanceVariable;
4794}
4795
4796template<typename IBaseInterface>
4797ID3DX11EffectInterfaceVariable * TUncastableVariable<IBaseInterface>::AsInterface()
4798{
4799    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsInterface";
4800    DPF(0, "%s: Invalid typecast", pFuncName);
4801    return &g_InvalidInterfaceVariable;
4802}
4803
4804template<typename IBaseInterface>
4805ID3DX11EffectShaderResourceVariable * TUncastableVariable<IBaseInterface>::AsShaderResource()
4806{
4807    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsShaderResource";
4808    DPF(0, "%s: Invalid typecast", pFuncName);
4809    return &g_InvalidShaderResourceVariable;
4810}
4811
4812template<typename IBaseInterface>
4813ID3DX11EffectUnorderedAccessViewVariable * TUncastableVariable<IBaseInterface>::AsUnorderedAccessView()
4814{
4815    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsUnorderedAccessView";
4816    DPF(0, "%s: Invalid typecast", pFuncName);
4817    return &g_InvalidUnorderedAccessViewVariable;
4818}
4819
4820template<typename IBaseInterface>
4821ID3DX11EffectRenderTargetViewVariable * TUncastableVariable<IBaseInterface>::AsRenderTargetView()
4822{
4823    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsRenderTargetView";
4824    DPF(0, "%s: Invalid typecast", pFuncName);
4825    return &g_InvalidRenderTargetViewVariable;
4826}
4827
4828template<typename IBaseInterface>
4829ID3DX11EffectDepthStencilViewVariable * TUncastableVariable<IBaseInterface>::AsDepthStencilView()
4830{
4831    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsDepthStencilView";
4832    DPF(0, "%s: Invalid typecast", pFuncName);
4833    return &g_InvalidDepthStencilViewVariable;
4834}
4835
4836template<typename IBaseInterface>
4837ID3DX11EffectConstantBuffer * TUncastableVariable<IBaseInterface>::AsConstantBuffer()
4838{
4839    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsConstantBuffer";
4840    DPF(0, "%s: Invalid typecast", pFuncName);
4841    return &g_InvalidConstantBuffer;
4842}
4843
4844template<typename IBaseInterface>
4845ID3DX11EffectShaderVariable * TUncastableVariable<IBaseInterface>::AsShader()
4846{
4847    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsShader";
4848    DPF(0, "%s: Invalid typecast", pFuncName);
4849    return &g_InvalidShaderVariable;
4850}
4851
4852template<typename IBaseInterface>
4853ID3DX11EffectBlendVariable * TUncastableVariable<IBaseInterface>::AsBlend()
4854{
4855    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsBlend";
4856    DPF(0, "%s: Invalid typecast", pFuncName);
4857    return &g_InvalidBlendVariable;
4858}
4859
4860template<typename IBaseInterface>
4861ID3DX11EffectDepthStencilVariable * TUncastableVariable<IBaseInterface>::AsDepthStencil()
4862{
4863    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsDepthStencil";
4864    DPF(0, "%s: Invalid typecast", pFuncName);
4865    return &g_InvalidDepthStencilVariable;
4866}
4867
4868template<typename IBaseInterface>
4869ID3DX11EffectRasterizerVariable * TUncastableVariable<IBaseInterface>::AsRasterizer()
4870{
4871    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsRasterizer";
4872    DPF(0, "%s: Invalid typecast", pFuncName);
4873    return &g_InvalidRasterizerVariable;
4874}
4875
4876template<typename IBaseInterface>
4877ID3DX11EffectSamplerVariable * TUncastableVariable<IBaseInterface>::AsSampler()
4878{
4879    static LPCSTR pFuncName = "ID3DX11EffectVariable::AsSampler";
4880    DPF(0, "%s: Invalid typecast", pFuncName);
4881    return &g_InvalidSamplerVariable;
4882}
4883
4884////////////////////////////////////////////////////////////////////////////////
4885// Macros to instantiate the myriad templates
4886////////////////////////////////////////////////////////////////////////////////
4887
4888// generates a global variable, annotation, global variable member, and annotation member of each struct type
4889#define GenerateReflectionClasses(Type, BaseInterface) \
4890struct S##Type##GlobalVariable : public T##Type##Variable<TGlobalVariable<BaseInterface>, false> { IUNKNOWN_IMP(S##Type##GlobalVariable, BaseInterface, ID3DX11EffectVariable); }; \
4891struct S##Type##Annotation : public T##Type##Variable<TAnnotation<BaseInterface>, true> { IUNKNOWN_IMP(S##Type##Annotation, BaseInterface, ID3DX11EffectVariable);}; \
4892struct S##Type##GlobalVariableMember : public T##Type##Variable<TVariable<TMember<BaseInterface> >, false> { IUNKNOWN_IMP(S##Type##GlobalVariableMember, BaseInterface, ID3DX11EffectVariable); }; \
4893struct S##Type##AnnotationMember : public T##Type##Variable<TVariable<TMember<BaseInterface> >, true> { IUNKNOWN_IMP(S##Type##AnnotationMember, BaseInterface, ID3DX11EffectVariable); };
4894
4895#define GenerateVectorReflectionClasses(Type, BaseType, BaseInterface) \
4896struct S##Type##GlobalVariable : public TVectorVariable<TGlobalVariable<BaseInterface>, false, BaseType> { IUNKNOWN_IMP(S##Type##GlobalVariable, BaseInterface, ID3DX11EffectVariable); }; \
4897struct S##Type##Annotation : public TVectorVariable<TAnnotation<BaseInterface>, true, BaseType> { IUNKNOWN_IMP(S##Type##Annotation, BaseInterface, ID3DX11EffectVariable);}; \
4898struct S##Type##GlobalVariableMember : public TVectorVariable<TVariable<TMember<BaseInterface> >, false, BaseType> { IUNKNOWN_IMP(S##Type##GlobalVariableMember, BaseInterface, ID3DX11EffectVariable);}; \
4899struct S##Type##AnnotationMember : public TVectorVariable<TVariable<TMember<BaseInterface> >, true, BaseType> { IUNKNOWN_IMP(S##Type##AnnotationMember, BaseInterface, ID3DX11EffectVariable);};
4900
4901#define GenerateReflectionGlobalOnlyClasses(Type) \
4902struct S##Type##GlobalVariable : public T##Type##Variable<TGlobalVariable<ID3DX11Effect##Type##Variable> > { IUNKNOWN_IMP(S##Type##GlobalVariable, ID3DX11Effect##Type##Variable, ID3DX11EffectVariable); }; \
4903struct S##Type##GlobalVariableMember : public T##Type##Variable<TVariable<TMember<ID3DX11Effect##Type##Variable> > > { IUNKNOWN_IMP(S##Type##GlobalVariableMember, ID3DX11Effect##Type##Variable, ID3DX11EffectVariable); }; \
4904
4905GenerateReflectionClasses(Numeric, ID3DX11EffectVariable);
4906GenerateReflectionClasses(FloatScalar, ID3DX11EffectScalarVariable);
4907GenerateReflectionClasses(IntScalar, ID3DX11EffectScalarVariable);
4908GenerateReflectionClasses(BoolScalar, ID3DX11EffectScalarVariable);
4909GenerateVectorReflectionClasses(FloatVector, ETVT_Float, ID3DX11EffectVectorVariable);
4910GenerateVectorReflectionClasses(BoolVector, ETVT_Bool, ID3DX11EffectVectorVariable);
4911GenerateVectorReflectionClasses(IntVector, ETVT_Int, ID3DX11EffectVectorVariable);
4912GenerateReflectionClasses(Matrix, ID3DX11EffectMatrixVariable);
4913GenerateReflectionClasses(String, ID3DX11EffectStringVariable);
4914GenerateReflectionGlobalOnlyClasses(ClassInstance);
4915GenerateReflectionGlobalOnlyClasses(Interface);
4916GenerateReflectionGlobalOnlyClasses(ShaderResource);
4917GenerateReflectionGlobalOnlyClasses(UnorderedAccessView);
4918GenerateReflectionGlobalOnlyClasses(RenderTargetView);
4919GenerateReflectionGlobalOnlyClasses(DepthStencilView);
4920GenerateReflectionGlobalOnlyClasses(Shader);
4921GenerateReflectionGlobalOnlyClasses(Blend);
4922GenerateReflectionGlobalOnlyClasses(DepthStencil);
4923GenerateReflectionGlobalOnlyClasses(Rasterizer);
4924GenerateReflectionGlobalOnlyClasses(Sampler);
4925
4926// Optimized matrix classes
4927struct SMatrix4x4ColumnMajorGlobalVariable : public TMatrix4x4Variable<TGlobalVariable<ID3DX11EffectMatrixVariable>, true> { IUNKNOWN_IMP(SMatrix4x4ColumnMajorGlobalVariable, ID3DX11EffectMatrixVariable, ID3DX11EffectVariable); };
4928struct SMatrix4x4RowMajorGlobalVariable : public TMatrix4x4Variable<TGlobalVariable<ID3DX11EffectMatrixVariable>, false> { IUNKNOWN_IMP(SMatrix4x4RowMajorGlobalVariable, ID3DX11EffectMatrixVariable, ID3DX11EffectVariable); };
4929
4930struct SMatrix4x4ColumnMajorGlobalVariableMember : public TMatrix4x4Variable<TVariable<TMember<ID3DX11EffectMatrixVariable> >, true> { IUNKNOWN_IMP(SMatrix4x4ColumnMajorGlobalVariableMember, ID3DX11EffectMatrixVariable, ID3DX11EffectVariable); };
4931struct SMatrix4x4RowMajorGlobalVariableMember : public TMatrix4x4Variable<TVariable<TMember<ID3DX11EffectMatrixVariable> >, false> { IUNKNOWN_IMP(SMatrix4x4RowMajorGlobalVariableMember, ID3DX11EffectMatrixVariable, ID3DX11EffectVariable); };
4932
4933// Optimized vector classes
4934struct SFloatVector4GlobalVariable : public TVector4Variable<TGlobalVariable<ID3DX11EffectVectorVariable> > { IUNKNOWN_IMP(SFloatVector4GlobalVariable, ID3DX11EffectVectorVariable, ID3DX11EffectVariable); };
4935struct SFloatVector4GlobalVariableMember : public TVector4Variable<TVariable<TMember<ID3DX11EffectVectorVariable> > > { IUNKNOWN_IMP(SFloatVector4GlobalVariableMember, ID3DX11EffectVectorVariable, ID3DX11EffectVariable); };
4936
4937// These 3 classes should never be used directly
4938
4939// The "base" global variable struct (all global variables should be the same size in bytes,
4940// but we pick this as the default).
4941struct SGlobalVariable : public TGlobalVariable<ID3DX11EffectVariable>
4942{
4943
4944};
4945
4946// The "base" annotation struct (all annotations should be the same size in bytes,
4947// but we pick this as the default).
4948struct SAnnotation : public TAnnotation<ID3DX11EffectVariable>
4949{
4950
4951};
4952
4953// The "base" variable member struct (all annotation/global variable members should be the
4954// same size in bytes, but we pick this as the default).
4955struct SMember : public TVariable<TMember<ID3DX11EffectVariable> >
4956{
4957
4958};
4959
4960// creates a new variable of the appropriate polymorphic type where pVar was
4961HRESULT PlacementNewVariable(_In_ void *pVar, _In_ SType *pType, _In_ bool IsAnnotation);
4962SMember * CreateNewMember(_In_ SType *pType, _In_ bool IsAnnotation);
4963
4964#pragma warning(pop)
4965