OSDN Git Service

#32713 初コミット。SVNrev567時点での、ファイルはbranch/140707(ReBuild XGVersion)から移行したもの。
[dtxmaniaxg-verk/dtxmaniaxg-verk-git.git] / SlimDXc_Jun2010(VC++2008) / external / Effects11 / EffectReflection.cpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 //  Copyright (C) Microsoft Corporation.  All Rights Reserved.
4 //
5 //  File:       EffectReflection.cpp
6 //  Content:    D3DX11 Effects public reflection APIs
7 //
8 //////////////////////////////////////////////////////////////////////////////
9
10 #include "pchfx.h"
11
12 namespace D3DX11Effects
13 {
14
15 SEffectInvalidType g_InvalidType;
16
17 SEffectInvalidScalarVariable g_InvalidScalarVariable;
18 SEffectInvalidVectorVariable g_InvalidVectorVariable;
19 SEffectInvalidMatrixVariable g_InvalidMatrixVariable;
20 SEffectInvalidStringVariable g_InvalidStringVariable;
21 SEffectInvalidClassInstanceVariable g_InvalidClassInstanceVariable;
22 SEffectInvalidInterfaceVariable g_InvalidInterfaceVariable;
23 SEffectInvalidShaderResourceVariable g_InvalidShaderResourceVariable;
24 SEffectInvalidUnorderedAccessViewVariable g_InvalidUnorderedAccessViewVariable;
25 SEffectInvalidRenderTargetViewVariable g_InvalidRenderTargetViewVariable;
26 SEffectInvalidDepthStencilViewVariable g_InvalidDepthStencilViewVariable;
27 SEffectInvalidConstantBuffer g_InvalidConstantBuffer;
28 SEffectInvalidShaderVariable g_InvalidShaderVariable;
29 SEffectInvalidBlendVariable g_InvalidBlendVariable;
30 SEffectInvalidDepthStencilVariable g_InvalidDepthStencilVariable;
31 SEffectInvalidRasterizerVariable g_InvalidRasterizerVariable;
32 SEffectInvalidSamplerVariable g_InvalidSamplerVariable;
33
34 SEffectInvalidPass g_InvalidPass;
35 SEffectInvalidTechnique g_InvalidTechnique;
36 SEffectInvalidGroup g_InvalidGroup;
37
38
39 //////////////////////////////////////////////////////////////////////////
40 // Helper routine implementations
41 //////////////////////////////////////////////////////////////////////////
42
43 ID3DX11EffectConstantBuffer * NoParentCB()
44 {
45     DPF(0, "ID3DX11EffectVariable::GetParentConstantBuffer: Variable does not have a parent constant buffer");
46     // have to typecast because the type of g_InvalidScalarVariable has not been declared yet
47     return &g_InvalidConstantBuffer;
48 }
49
50 ID3DX11EffectVariable * GetAnnotationByIndexHelper(const char *pClassName, UINT  Index, UINT  AnnotationCount, SAnnotation *pAnnotations)
51 {
52     if (Index >= AnnotationCount)
53     {
54         DPF(0, "%s::GetAnnotationByIndex: Invalid index (%d, total: %d)", pClassName, Index, AnnotationCount);
55         return &g_InvalidScalarVariable;
56     }
57
58     return pAnnotations + Index;
59 }
60
61 ID3DX11EffectVariable * GetAnnotationByNameHelper(const char *pClassName, LPCSTR Name, UINT  AnnotationCount, SAnnotation *pAnnotations)
62 {
63     UINT  i;
64     for (i = 0; i < AnnotationCount; ++ i)
65     {
66         if (strcmp(pAnnotations[i].pName, Name) == 0)
67         {
68             return pAnnotations + i;
69         }
70     }
71
72     DPF(0, "%s::GetAnnotationByName: Annotation [%s] not found", pClassName, Name);
73     return &g_InvalidScalarVariable;
74 }
75
76 //////////////////////////////////////////////////////////////////////////
77 // Effect routines to pool interfaces
78 //////////////////////////////////////////////////////////////////////////
79
80 ID3DX11EffectType * CEffect::CreatePooledSingleElementTypeInterface(SType *pType)
81 {
82     UINT  i;
83
84     if (IsOptimized())
85     {
86         DPF(0, "ID3DX11Effect: Cannot create new type interfaces since the effect has been Optimize()'ed");
87         return &g_InvalidType;
88     }
89
90     for (i = 0; i < m_pTypeInterfaces.GetSize(); ++ i)
91     {
92         if (m_pTypeInterfaces[i]->pType == pType)
93         {
94             return (SSingleElementType*)m_pTypeInterfaces[i];
95         }
96     }
97     SSingleElementType *pNewType;
98     if (NULL == (pNewType = NEW SSingleElementType))
99     {
100         DPF(0, "ID3DX11Effect: Out of memory while trying to create new type interface");
101         return &g_InvalidType;
102     }
103
104     pNewType->pType = pType;
105     m_pTypeInterfaces.Add(pNewType);
106
107     return pNewType;
108 }
109
110 // Create a member variable (via GetMemberBy* or GetElement)
111 ID3DX11EffectVariable * CEffect::CreatePooledVariableMemberInterface(TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity, SVariable *pMember, UDataPointer Data, BOOL IsSingleElement, UINT Index)
112 {
113     BOOL IsAnnotation;
114     UINT  i;
115
116     if (IsOptimized())
117     {
118         DPF(0, "ID3DX11Effect: Cannot create new variable interfaces since the effect has been Optimize()'ed");
119         return &g_InvalidScalarVariable;
120     }
121
122     for (i = 0; i < m_pMemberInterfaces.GetSize(); ++ i)
123     {
124         if (m_pMemberInterfaces[i]->pType == pMember->pType && 
125             m_pMemberInterfaces[i]->pName == pMember->pName &&
126             m_pMemberInterfaces[i]->pSemantic == pMember->pSemantic &&
127             m_pMemberInterfaces[i]->Data.pGeneric == Data.pGeneric &&
128             m_pMemberInterfaces[i]->IsSingleElement == IsSingleElement &&
129             ((SMember*)m_pMemberInterfaces[i])->pTopLevelEntity == pTopLevelEntity)
130         {
131             return (ID3DX11EffectVariable *) m_pMemberInterfaces[i];
132         }
133     }
134
135     // is this annotation or runtime data?
136     if( pTopLevelEntity->pEffect->IsReflectionData(pTopLevelEntity) )
137     {
138         D3DXASSERT( pTopLevelEntity->pEffect->IsReflectionData(Data.pGeneric) );
139         IsAnnotation = TRUE;
140     }
141     else
142     {
143         // if the heap is empty, we are still loading the Effect, and thus creating a member for a variable initializer
144         // ex. Interface myInt = myClassArray[2];
145         if( pTopLevelEntity->pEffect->m_Heap.GetSize() > 0 )
146         {
147             D3DXASSERT( pTopLevelEntity->pEffect->IsRuntimeData(pTopLevelEntity) );
148             if (!pTopLevelEntity->pType->IsObjectType(EOT_String))
149             {
150                 // strings are funny; their data is reflection data, so ignore those
151                 D3DXASSERT( pTopLevelEntity->pEffect->IsRuntimeData(Data.pGeneric) );
152             }
153         }
154         IsAnnotation = FALSE;
155     }
156
157     SMember *pNewMember;
158
159     if (NULL == (pNewMember = CreateNewMember((SType*)pMember->pType, IsAnnotation)))
160     {
161         DPF(0, "ID3DX11Effect: Out of memory while trying to create new member variable interface");
162         return &g_InvalidScalarVariable;
163     }
164     
165     pNewMember->pType = pMember->pType;
166     pNewMember->pName = pMember->pName;
167     pNewMember->pSemantic = pMember->pSemantic;
168     pNewMember->Data.pGeneric = Data.pGeneric;
169     pNewMember->IsSingleElement = IsSingleElement;
170     pNewMember->pTopLevelEntity = pTopLevelEntity;
171
172     if( IsSingleElement && pMember->pMemberData )
173     {
174         D3DXASSERT( !IsAnnotation );
175         // This is an element of a global variable array
176         pNewMember->pMemberData = pMember->pMemberData + Index;
177     }
178
179     if (FAILED(m_pMemberInterfaces.Add(pNewMember)))
180     {
181         SAFE_DELETE(pNewMember);
182         DPF(0, "ID3DX11Effect: Out of memory while trying to create new member variable interface");
183         return &g_InvalidScalarVariable;
184     }
185
186     return (ID3DX11EffectVariable *) pNewMember;
187 }
188
189 //////////////////////////////////////////////////////////////////////////
190 // ID3DX11EffectType (SType, SSingleElementType implementations)
191 //////////////////////////////////////////////////////////////////////////
192
193 static ID3DX11EffectType * GetTypeByIndexHelper(UINT Index, UINT  VariableCount, 
194                                                SVariable *pVariables, UINT  SizeOfVariableType)
195 {
196     LPCSTR pFuncName = "ID3DX11EffectType::GetMemberTypeByIndex";
197
198     if (Index >= VariableCount)
199     {
200         DPF(0, "%s: Invalid index (%d, total: %d)", pFuncName, Index, VariableCount);
201         return &g_InvalidType;
202     }
203
204     SVariable *pVariable = (SVariable *)((BYTE *)pVariables + Index * SizeOfVariableType);
205     if (NULL == pVariable->pName)
206     {
207         DPF(0, "%s: Cannot get member types; Effect has been Optimize()'ed", pFuncName);
208         return &g_InvalidType;
209     }
210
211     return (ID3DX11EffectType *) pVariable->pType;
212 }
213
214 static ID3DX11EffectType * GetTypeByNameHelper(LPCSTR Name, UINT  VariableCount, 
215                                               SVariable *pVariables, UINT  SizeOfVariableType)
216 {
217     LPCSTR pFuncName = "ID3DX11EffectType::GetMemberTypeByName";
218
219     if (NULL == Name)
220     {
221         DPF(0, "%s: Parameter Name was NULL.", pFuncName);
222         return &g_InvalidType;
223     }
224
225     UINT  i;
226     SVariable *pVariable;
227
228     for (i = 0; i < VariableCount; ++ i)
229     {
230         pVariable = (SVariable *)((BYTE *)pVariables + i * SizeOfVariableType);
231         if (NULL == pVariable->pName)
232         {
233             DPF(0, "%s: Cannot get member types; Effect has been Optimize()'ed", pFuncName);
234             return &g_InvalidType;
235         }
236         if (strcmp(pVariable->pName, Name) == 0)
237         {
238             return (ID3DX11EffectType *) pVariable->pType;
239         }
240     }
241
242     DPF(0, "%s: Member type [%s] not found", pFuncName, Name);
243     return &g_InvalidType;
244 }
245
246
247 static ID3DX11EffectType * GetTypeBySemanticHelper(LPCSTR Semantic, UINT  VariableCount, 
248                                                   SVariable *pVariables, UINT  SizeOfVariableType)
249 {
250     LPCSTR pFuncName = "ID3DX11EffectType::GetMemberTypeBySemantic";
251
252     if (NULL == Semantic)
253     {
254         DPF(0, "%s: Parameter Semantic was NULL.", pFuncName);
255         return &g_InvalidType;
256     }
257
258     UINT  i;
259     SVariable *pVariable;
260
261     for (i = 0; i < VariableCount; ++ i)
262     {
263         pVariable = (SVariable *)((BYTE *)pVariables + i * SizeOfVariableType);
264         if (NULL == pVariable->pName)
265         {
266             DPF(0, "%s: Cannot get member types; Effect has been Optimize()'ed", pFuncName);
267             return &g_InvalidType;
268         }
269         if (NULL != pVariable->pSemantic &&
270             _stricmp(pVariable->pSemantic, Semantic) == 0)
271         {
272             return (ID3DX11EffectType *) pVariable->pType;
273         }
274     }
275
276     DPF(0, "%s: Member type with semantic [%s] not found", pFuncName, Semantic);
277     return &g_InvalidType;
278 }
279
280 ID3DX11EffectType * SType::GetMemberTypeByIndex(UINT Index)
281 {
282     if (VarType != EVT_Struct)
283     {
284         DPF(0, "ID3DX11EffectType::GetMemberTypeByIndex: This interface does not refer to a structure");
285         return &g_InvalidType;
286     }
287
288     return GetTypeByIndexHelper(Index, StructType.Members, StructType.pMembers, sizeof(SVariable));
289 }
290
291 ID3DX11EffectType * SType::GetMemberTypeByName(LPCSTR Name)
292 {
293     if (VarType != EVT_Struct)
294     {
295         DPF(0, "ID3DX11EffectType::GetMemberTypeByName: This interface does not refer to a structure");
296         return &g_InvalidType;
297     }
298
299     return GetTypeByNameHelper(Name, StructType.Members, StructType.pMembers, sizeof(SVariable));
300 }
301
302 ID3DX11EffectType * SType::GetMemberTypeBySemantic(LPCSTR Semantic)
303 {
304     if (VarType != EVT_Struct)
305     {
306         DPF(0, "ID3DX11EffectType::GetMemberTypeBySemantic: This interface does not refer to a structure");
307         return &g_InvalidType;
308     }
309
310     return GetTypeBySemanticHelper(Semantic, StructType.Members, StructType.pMembers, sizeof(SVariable));
311 }
312
313 LPCSTR SType::GetMemberName(UINT Index)
314 {
315     LPCSTR pFuncName = "ID3DX11EffectType::GetMemberName";
316
317     if (VarType != EVT_Struct)
318     {
319         DPF(0, "%s: This interface does not refer to a structure", pFuncName);
320         return NULL;
321     }
322
323     if (Index >= StructType.Members)
324     {
325         DPF(0, "%s: Invalid index (%d, total: %d)", pFuncName, Index, StructType.Members);
326         return NULL;
327     }
328
329     SVariable *pVariable = StructType.pMembers + Index;
330
331     if (NULL == pVariable->pName)
332     {
333         DPF(0, "%s: Cannot get member names; Effect has been Optimize()'ed", pFuncName);
334         return NULL;
335     }
336
337     return pVariable->pName;
338 }
339
340 LPCSTR SType::GetMemberSemantic(UINT Index)
341 {
342     LPCSTR pFuncName = "ID3DX11EffectType::GetMemberSemantic";
343
344     if (VarType != EVT_Struct)
345     {
346         DPF(0, "%s: This interface does not refer to a structure", pFuncName);
347         return NULL;
348     }
349
350     if (Index >= StructType.Members)
351     {
352         DPF(0, "%s: Invalid index (%d, total: %d)", pFuncName, Index, StructType.Members);
353         return NULL;
354     }
355
356     SVariable *pVariable = StructType.pMembers + Index;
357
358     if (NULL == pVariable->pName)
359     {
360         DPF(0, "%s: Cannot get member semantics; Effect has been Optimize()'ed", pFuncName);
361         return NULL;
362     }
363
364     return pVariable->pSemantic;
365 }
366
367 HRESULT SType::GetDescHelper(D3DX11_EFFECT_TYPE_DESC *pDesc, BOOL IsSingleElement) const
368 {
369     HRESULT hr = S_OK;
370     LPCSTR pFuncName = "ID3DX11EffectType::GetDesc";
371
372     VERIFYPARAMETER(pDesc);
373     
374     pDesc->TypeName = pTypeName;
375
376     // intentionally return 0 so they know it's not a single element array
377     pDesc->Elements = IsSingleElement ? 0 : Elements;
378     pDesc->PackedSize = GetTotalPackedSize(IsSingleElement);
379     pDesc->UnpackedSize = GetTotalUnpackedSize(IsSingleElement);
380     pDesc->Stride = Stride;
381
382     switch (VarType)
383     {
384     case EVT_Numeric:
385         switch (NumericType.NumericLayout)
386         {
387         case ENL_Matrix:
388             if (NumericType.IsColumnMajor)
389             {
390                 pDesc->Class = D3D10_SVC_MATRIX_COLUMNS;
391             }
392             else
393             {
394                 pDesc->Class = D3D10_SVC_MATRIX_ROWS;
395             }
396             break;
397         case ENL_Vector:
398             pDesc->Class = D3D10_SVC_VECTOR;
399             break;
400         case ENL_Scalar:
401             pDesc->Class = D3D10_SVC_SCALAR;
402             break;
403         default:
404             D3DXASSERT(0);
405         }
406
407         switch (NumericType.ScalarType)
408         {
409         case EST_Bool:
410             pDesc->Type = D3D10_SVT_BOOL;
411             break;
412         case EST_Int:
413             pDesc->Type = D3D10_SVT_INT;
414             break;
415         case EST_UInt:
416             pDesc->Type = D3D10_SVT_UINT;
417             break;
418         case EST_Float:
419             pDesc->Type = D3D10_SVT_FLOAT;
420             break;
421         default:
422             D3DXASSERT(0);
423         }
424
425         pDesc->Rows = NumericType.Rows;
426         pDesc->Columns = NumericType.Columns;
427         pDesc->Members = 0;
428
429         break;
430
431     case EVT_Struct:
432         pDesc->Rows = 0;
433         pDesc->Columns = 0;
434         pDesc->Members = StructType.Members;
435         if( StructType.ImplementsInterface )
436         {
437             pDesc->Class = D3D11_SVC_INTERFACE_CLASS;
438         }
439         else
440         {
441             pDesc->Class = D3D10_SVC_STRUCT;
442         }
443         pDesc->Type = D3D10_SVT_VOID;
444         break;
445
446     case EVT_Interface:
447         pDesc->Rows = 0;
448         pDesc->Columns = 0;
449         pDesc->Members = 0;
450         pDesc->Class = D3D11_SVC_INTERFACE_POINTER;
451         pDesc->Type = D3D11_SVT_INTERFACE_POINTER;
452         break;
453
454     case EVT_Object:
455         pDesc->Rows = 0;
456         pDesc->Columns = 0;
457         pDesc->Members = 0;
458         pDesc->Class = D3D10_SVC_OBJECT;            
459
460         switch (ObjectType)
461         {
462         case EOT_String:
463             pDesc->Type = D3D10_SVT_STRING;
464             break;
465         case EOT_Blend:
466             pDesc->Type = D3D10_SVT_BLEND; 
467             break;
468         case EOT_DepthStencil:
469             pDesc->Type = D3D10_SVT_DEPTHSTENCIL;
470             break;
471         case EOT_Rasterizer:
472             pDesc->Type = D3D10_SVT_RASTERIZER;
473             break;
474         case EOT_PixelShader:
475         case EOT_PixelShader5:
476             pDesc->Type = D3D10_SVT_PIXELSHADER;
477             break;
478         case EOT_VertexShader:
479         case EOT_VertexShader5:
480             pDesc->Type = D3D10_SVT_VERTEXSHADER;
481             break;
482         case EOT_GeometryShader:
483         case EOT_GeometryShaderSO:
484         case EOT_GeometryShader5:
485             pDesc->Type = D3D10_SVT_GEOMETRYSHADER;
486             break;
487         case EOT_HullShader5:
488             pDesc->Type = D3D11_SVT_HULLSHADER;
489             break;
490         case EOT_DomainShader5:
491             pDesc->Type = D3D11_SVT_DOMAINSHADER;
492             break;
493         case EOT_ComputeShader5:
494             pDesc->Type = D3D11_SVT_COMPUTESHADER;
495             break;
496         case EOT_Texture:
497             pDesc->Type = D3D10_SVT_TEXTURE;
498             break;
499         case EOT_Texture1D:
500             pDesc->Type = D3D10_SVT_TEXTURE1D;
501             break;
502         case EOT_Texture1DArray:
503             pDesc->Type = D3D10_SVT_TEXTURE1DARRAY;
504             break;
505         case EOT_Texture2D:
506             pDesc->Type = D3D10_SVT_TEXTURE2D;
507             break;
508         case EOT_Texture2DArray:
509             pDesc->Type = D3D10_SVT_TEXTURE2DARRAY;
510             break;
511         case EOT_Texture2DMS:
512             pDesc->Type = D3D10_SVT_TEXTURE2DMS;
513             break;
514         case EOT_Texture2DMSArray:
515             pDesc->Type = D3D10_SVT_TEXTURE2DMSARRAY;
516             break;
517         case EOT_Texture3D:
518             pDesc->Type = D3D10_SVT_TEXTURE3D;
519             break;
520         case EOT_TextureCube:
521             pDesc->Type = D3D10_SVT_TEXTURECUBE;
522             break;
523         case EOT_TextureCubeArray:
524             pDesc->Type = D3D10_SVT_TEXTURECUBEARRAY;
525             break;
526         case EOT_Buffer:
527             pDesc->Type = D3D10_SVT_BUFFER;
528             break;
529         case EOT_Sampler:
530             pDesc->Type = D3D10_SVT_SAMPLER;
531             break;
532         case EOT_RenderTargetView:
533             pDesc->Type = D3D10_SVT_RENDERTARGETVIEW;
534             break;
535         case EOT_DepthStencilView:
536             pDesc->Type = D3D10_SVT_DEPTHSTENCILVIEW;
537             break;
538         case EOT_RWTexture1D:
539             pDesc->Type = D3D11_SVT_RWTEXTURE1D;
540             break;
541         case EOT_RWTexture1DArray:
542             pDesc->Type = D3D11_SVT_RWTEXTURE1DARRAY;
543             break;
544         case EOT_RWTexture2D:
545             pDesc->Type = D3D11_SVT_RWTEXTURE2D;
546             break;
547         case EOT_RWTexture2DArray:
548             pDesc->Type = D3D11_SVT_RWTEXTURE2DARRAY;
549             break;
550         case EOT_RWTexture3D:
551             pDesc->Type = D3D11_SVT_RWTEXTURE3D;
552             break;
553         case EOT_RWBuffer:
554             pDesc->Type = D3D11_SVT_RWBUFFER;
555             break;
556         case EOT_ByteAddressBuffer:
557             pDesc->Type = D3D11_SVT_BYTEADDRESS_BUFFER;
558             break;
559         case EOT_RWByteAddressBuffer:
560             pDesc->Type = D3D11_SVT_RWBYTEADDRESS_BUFFER;
561             break;
562         case EOT_StructuredBuffer:
563             pDesc->Type = D3D11_SVT_STRUCTURED_BUFFER;
564             break;
565         case EOT_RWStructuredBuffer:
566         case EOT_RWStructuredBufferAlloc:
567         case EOT_RWStructuredBufferConsume:
568             pDesc->Type = D3D11_SVT_RWSTRUCTURED_BUFFER;
569             break;
570         case EOT_AppendStructuredBuffer:
571             pDesc->Type = D3D11_SVT_APPEND_STRUCTURED_BUFFER;
572             break;
573         case EOT_ConsumeStructuredBuffer:
574             pDesc->Type = D3D11_SVT_CONSUME_STRUCTURED_BUFFER;
575             break;
576
577         default:
578             D3DXASSERT(0);
579         }
580         break;
581
582     default:
583         D3DXASSERT(0);
584     }
585
586 lExit:
587     return hr;
588
589 }
590
591 ////////////////////////////////////////////////////////////////////////////////
592 // ID3DX11EffectShaderVariable (SAnonymousShader implementation)
593 ////////////////////////////////////////////////////////////////////////////////
594
595 SAnonymousShader::SAnonymousShader(SShaderBlock *pBlock)
596 {
597     pShaderBlock = pBlock;
598 }
599
600 BOOL SAnonymousShader::IsValid()
601 {
602     return pShaderBlock && pShaderBlock->IsValid;
603 }
604
605 ID3DX11EffectType * SAnonymousShader::GetType()
606 {
607     return (ID3DX11EffectType *) this;
608 }
609
610 HRESULT SAnonymousShader::GetDesc(D3DX11_EFFECT_VARIABLE_DESC *pDesc)
611 {
612     pDesc->Annotations = 0;
613     pDesc->Flags = 0;
614
615     pDesc->Name = "$Anonymous";
616     pDesc->Semantic = NULL;
617     pDesc->BufferOffset = 0;
618
619     return S_OK;
620 }
621
622 ID3DX11EffectVariable * SAnonymousShader::GetAnnotationByIndex(UINT Index)
623 {
624     DPF(0, "ID3DX11EffectVariable::GetAnnotationByIndex: Anonymous shaders cannot have annotations");
625     return &g_InvalidScalarVariable;
626 }
627
628 ID3DX11EffectVariable * SAnonymousShader::GetAnnotationByName(LPCSTR Name)
629 {
630     DPF(0, "ID3DX11EffectVariable::GetAnnotationByName: Anonymous shaders cannot have annotations");
631     return &g_InvalidScalarVariable;
632 }
633
634 ID3DX11EffectVariable * SAnonymousShader::GetMemberByIndex(UINT  Index)
635 {
636     DPF(0, "ID3DX11EffectVariable::GetMemberByIndex: Variable is not a structure");
637     return &g_InvalidScalarVariable;
638 }
639
640 ID3DX11EffectVariable * SAnonymousShader::GetMemberByName(LPCSTR Name)
641 {
642     DPF(0, "ID3DX11EffectVariable::GetMemberByName: Variable is not a structure");
643     return &g_InvalidScalarVariable;
644 }
645
646 ID3DX11EffectVariable * SAnonymousShader::GetMemberBySemantic(LPCSTR Semantic)
647 {
648     DPF(0, "ID3DX11EffectVariable::GetMemberBySemantic: Variable is not a structure");
649     return &g_InvalidScalarVariable;
650 }
651
652 ID3DX11EffectVariable * SAnonymousShader::GetElement(UINT Index)
653 {
654     DPF(0, "ID3DX11EffectVariable::GetElement: Anonymous shaders cannot have elements");
655     return &g_InvalidScalarVariable;
656 }
657
658 ID3DX11EffectConstantBuffer * SAnonymousShader::GetParentConstantBuffer()
659 {
660     return NoParentCB();
661 }
662
663 ID3DX11EffectShaderVariable * SAnonymousShader::AsShader()
664 {
665     return (ID3DX11EffectShaderVariable *) this;
666 }
667
668 HRESULT SAnonymousShader::SetRawValue(CONST void *pData, UINT Offset, UINT Count) 
669
670     return ObjectSetRawValue(); 
671 }
672
673 HRESULT SAnonymousShader::GetRawValue(__out_bcount(Count) void *pData, UINT Offset, UINT Count) 
674
675     return ObjectGetRawValue(); 
676 }
677
678 #define ANONYMOUS_SHADER_INDEX_CHECK() \
679     HRESULT hr = S_OK; \
680     if (0 != ShaderIndex) \
681     { \
682         DPF(0, "%s: Invalid index specified", pFuncName); \
683         VH(E_INVALIDARG); \
684     } \
685
686 HRESULT SAnonymousShader::GetShaderDesc(UINT ShaderIndex, D3DX11_EFFECT_SHADER_DESC *pDesc)
687 {
688     LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetShaderDesc";
689
690     ANONYMOUS_SHADER_INDEX_CHECK();
691
692     pShaderBlock->GetShaderDesc(pDesc, TRUE);
693
694 lExit:
695     return hr;
696 }
697
698 HRESULT SAnonymousShader::GetVertexShader(UINT ShaderIndex, ID3D11VertexShader **ppVS)
699 {
700     LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetVertexShader";
701
702     ANONYMOUS_SHADER_INDEX_CHECK();
703
704     VH( pShaderBlock->GetVertexShader(ppVS) );
705
706 lExit:
707     return hr;
708 }
709
710 HRESULT SAnonymousShader::GetGeometryShader(UINT ShaderIndex, ID3D11GeometryShader **ppGS)
711 {
712     LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetGeometryShader";
713
714     ANONYMOUS_SHADER_INDEX_CHECK();
715
716     VH( pShaderBlock->GetGeometryShader(ppGS) );
717
718 lExit:
719     return hr;
720 }
721
722 HRESULT SAnonymousShader::GetPixelShader(UINT ShaderIndex, ID3D11PixelShader **ppPS)
723 {
724     LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetPixelShader";
725
726     ANONYMOUS_SHADER_INDEX_CHECK();
727
728     VH( pShaderBlock->GetPixelShader(ppPS) );
729
730 lExit:
731     return hr;
732 }
733
734 HRESULT SAnonymousShader::GetHullShader(UINT ShaderIndex, ID3D11HullShader **ppHS)
735 {
736     LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetHullShader";
737
738     ANONYMOUS_SHADER_INDEX_CHECK();
739
740     VH( pShaderBlock->GetHullShader(ppHS) );
741
742 lExit:
743     return hr;
744 }
745
746 HRESULT SAnonymousShader::GetDomainShader(UINT ShaderIndex, ID3D11DomainShader **ppCS)
747 {
748     LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetDomainShader";
749
750     ANONYMOUS_SHADER_INDEX_CHECK();
751
752     VH( pShaderBlock->GetDomainShader(ppCS) );
753
754 lExit:
755     return hr;
756 }
757
758 HRESULT SAnonymousShader::GetComputeShader(UINT ShaderIndex, ID3D11ComputeShader **ppCS)
759 {
760     LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetComputeShader";
761
762     ANONYMOUS_SHADER_INDEX_CHECK();
763
764     VH( pShaderBlock->GetComputeShader(ppCS) );
765
766 lExit:
767     return hr;
768 }
769
770 HRESULT SAnonymousShader::GetInputSignatureElementDesc(UINT ShaderIndex, UINT Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
771 {
772     LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetInputSignatureElementDesc";
773
774     ANONYMOUS_SHADER_INDEX_CHECK();
775
776     VH( pShaderBlock->GetSignatureElementDesc(SShaderBlock::ST_Input, Element, pDesc) );
777
778 lExit:
779     return hr;
780 }
781
782 HRESULT SAnonymousShader::GetOutputSignatureElementDesc(UINT ShaderIndex, UINT Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
783 {
784     LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetOutputSignatureElementDesc";
785
786     ANONYMOUS_SHADER_INDEX_CHECK();
787
788     VH( pShaderBlock->GetSignatureElementDesc(SShaderBlock::ST_Output, Element, pDesc) );
789
790 lExit:
791     return hr;
792 }
793
794 HRESULT SAnonymousShader::GetPatchConstantSignatureElementDesc(UINT ShaderIndex, UINT Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
795 {
796     LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetPatchConstantSignatureElementDesc";
797
798     ANONYMOUS_SHADER_INDEX_CHECK();
799
800     VH( pShaderBlock->GetSignatureElementDesc(SShaderBlock::ST_PatchConstant, Element, pDesc) );
801
802 lExit:
803     return hr;
804 }
805
806 HRESULT SAnonymousShader::GetDesc(D3DX11_EFFECT_TYPE_DESC *pDesc)
807 {
808     pDesc->Class = D3D10_SVC_OBJECT;
809
810     switch (pShaderBlock->GetShaderType())
811     {
812     case EOT_VertexShader:
813     case EOT_VertexShader5:
814         pDesc->TypeName = "vertexshader";
815         pDesc->Type = D3D10_SVT_VERTEXSHADER;
816         break;
817     case EOT_GeometryShader:
818     case EOT_GeometryShader5:
819         pDesc->TypeName = "geometryshader";
820         pDesc->Type = D3D10_SVT_GEOMETRYSHADER;
821         break;
822     case EOT_PixelShader:
823     case EOT_PixelShader5:
824         pDesc->TypeName = "pixelshader";
825         pDesc->Type = D3D10_SVT_PIXELSHADER;
826         break;
827     case EOT_HullShader5:
828         pDesc->TypeName = "Hullshader";
829         pDesc->Type = D3D11_SVT_HULLSHADER;
830         break;
831     case EOT_DomainShader5:
832         pDesc->TypeName = "Domainshader";
833         pDesc->Type = D3D11_SVT_DOMAINSHADER;
834         break;
835     case EOT_ComputeShader5:
836         pDesc->TypeName = "Computeshader";
837         pDesc->Type = D3D11_SVT_COMPUTESHADER;
838         break;
839     }
840
841     pDesc->Elements = 0;
842     pDesc->Members = 0;
843     pDesc->Rows = 0;
844     pDesc->Columns = 0;
845     pDesc->PackedSize = 0;
846     pDesc->UnpackedSize = 0;
847     pDesc->Stride = 0;
848
849     return S_OK;
850 }
851
852 ID3DX11EffectType * SAnonymousShader::GetMemberTypeByIndex(UINT  Index)
853 {
854     DPF(0, "ID3DX11EffectType::GetMemberTypeByIndex: This interface does not refer to a structure");
855     return &g_InvalidType;
856 }
857
858 ID3DX11EffectType * SAnonymousShader::GetMemberTypeByName(LPCSTR Name)
859 {
860     DPF(0, "ID3DX11EffectType::GetMemberTypeByName: This interface does not refer to a structure");
861     return &g_InvalidType;
862 }
863
864 ID3DX11EffectType * SAnonymousShader::GetMemberTypeBySemantic(LPCSTR Semantic)
865 {
866     DPF(0, "ID3DX11EffectType::GetMemberTypeBySemantic: This interface does not refer to a structure");
867     return &g_InvalidType;
868 }
869
870 LPCSTR SAnonymousShader::GetMemberName(UINT Index)
871 {
872     DPF(0, "ID3DX11EffectType::GetMemberName: This interface does not refer to a structure");
873     return NULL;
874 }
875
876 LPCSTR SAnonymousShader::GetMemberSemantic(UINT Index)
877 {
878     DPF(0, "ID3DX11EffectType::GetMemberSemantic: This interface does not refer to a structure");
879     return NULL;
880 }
881
882 //////////////////////////////////////////////////////////////////////////
883 // ID3DX11EffectConstantBuffer (SConstantBuffer implementation)
884 //////////////////////////////////////////////////////////////////////////
885
886 BOOL SConstantBuffer::IsValid()
887 {
888     return TRUE;
889 }
890
891 ID3DX11EffectType * SConstantBuffer::GetType()
892 {
893     return (ID3DX11EffectType *) this;
894 }
895
896 HRESULT SConstantBuffer::GetDesc(D3DX11_EFFECT_VARIABLE_DESC *pDesc)
897 {
898     pDesc->Annotations = AnnotationCount;
899     pDesc->Flags = 0;
900
901     pDesc->Name = pName;
902     pDesc->Semantic = NULL;
903     pDesc->BufferOffset = 0;
904
905     if (ExplicitBindPoint != -1)
906     {
907         pDesc->ExplicitBindPoint = ExplicitBindPoint;
908         pDesc->Flags |= D3DX11_EFFECT_VARIABLE_EXPLICIT_BIND_POINT;
909     }
910     else
911     {
912         pDesc->ExplicitBindPoint = 0;
913     }
914
915     return S_OK;
916 }
917
918 ID3DX11EffectVariable * SConstantBuffer::GetAnnotationByIndex(UINT  Index)
919 {
920     return GetAnnotationByIndexHelper("ID3DX11EffectVariable", Index, AnnotationCount, pAnnotations);
921 }
922
923 ID3DX11EffectVariable * SConstantBuffer::GetAnnotationByName(LPCSTR Name)
924 {
925     return GetAnnotationByNameHelper("ID3DX11EffectVariable", Name, AnnotationCount, pAnnotations);
926 }
927
928 ID3DX11EffectVariable * SConstantBuffer::GetMemberByIndex(UINT  Index)
929 {
930     SGlobalVariable *pMember;
931     UDataPointer dataPtr;
932
933     if (IsEffectOptimized)
934     {
935         DPF(0, "ID3DX11EffectVariable::GetMemberByIndex: Cannot get members; effect has been Optimize()'ed");
936         return &g_InvalidScalarVariable;
937     }
938
939     if (!GetVariableByIndexHelper<SGlobalVariable>(Index, VariableCount, (SGlobalVariable*)pVariables, 
940         NULL, &pMember, &dataPtr.pGeneric))
941     {
942         return &g_InvalidScalarVariable;
943     }
944
945     return (ID3DX11EffectVariable *) pMember;
946 }
947
948 ID3DX11EffectVariable * SConstantBuffer::GetMemberByName(LPCSTR Name)
949 {
950     SGlobalVariable *pMember;
951     UDataPointer dataPtr;
952     UINT index;
953
954     if (IsEffectOptimized)
955     {
956         DPF(0, "ID3DX11EffectVariable::GetMemberByName: Cannot get members; effect has been Optimize()'ed");
957         return &g_InvalidScalarVariable;
958     }
959
960     if (!GetVariableByNameHelper<SGlobalVariable>(Name, VariableCount, (SGlobalVariable*)pVariables, 
961         NULL, &pMember, &dataPtr.pGeneric, &index))
962     {
963         return &g_InvalidScalarVariable;
964     }
965
966     return (ID3DX11EffectVariable *) pMember;
967 }
968
969 ID3DX11EffectVariable * SConstantBuffer::GetMemberBySemantic(LPCSTR Semantic)
970 {
971     SGlobalVariable *pMember;
972     UDataPointer dataPtr;
973     UINT index;
974
975     if (IsEffectOptimized)
976     {
977         DPF(0, "ID3DX11EffectVariable::GetMemberBySemantic: Cannot get members; effect has been Optimize()'ed");
978         return &g_InvalidScalarVariable;
979     }
980
981     if (!GetVariableBySemanticHelper<SGlobalVariable>(Semantic, VariableCount, (SGlobalVariable*)pVariables, 
982         NULL, &pMember, &dataPtr.pGeneric, &index))
983     {
984         return &g_InvalidScalarVariable;
985     }
986
987     return (ID3DX11EffectVariable *) pMember;
988 }
989
990 ID3DX11EffectVariable * SConstantBuffer::GetElement(UINT  Index)
991 {
992     LPCSTR pFuncName = "ID3DX11EffectVariable::GetElement";
993     DPF(0, "%s: This interface does not refer to an array", pFuncName);
994     return &g_InvalidScalarVariable;
995 }
996
997 ID3DX11EffectConstantBuffer * SConstantBuffer::GetParentConstantBuffer()
998 {
999     LPCSTR pFuncName = "ID3DX11EffectVariable::GetParentConstantBuffer";
1000     DPF(0, "%s: Constant buffers do not have parent constant buffers", pFuncName);
1001     return &g_InvalidConstantBuffer;
1002 }
1003
1004 ID3DX11EffectConstantBuffer * SConstantBuffer::AsConstantBuffer()
1005 {
1006     return (ID3DX11EffectConstantBuffer *) this;
1007 }
1008
1009 HRESULT SConstantBuffer::GetDesc(D3DX11_EFFECT_TYPE_DESC *pDesc)
1010 {
1011     pDesc->TypeName = IsTBuffer ? "tbuffer" : "cbuffer";
1012     pDesc->Class = D3D10_SVC_OBJECT;
1013     pDesc->Type = IsTBuffer ? D3D10_SVT_TBUFFER : D3D10_SVT_CBUFFER;
1014
1015     pDesc->Elements = 0;
1016     pDesc->Members = VariableCount;
1017     pDesc->Rows = 0;
1018     pDesc->Columns = 0;
1019
1020     UINT  i;
1021     pDesc->PackedSize = 0;
1022     for (i = 0; i < VariableCount; ++ i)
1023     {
1024         pDesc->PackedSize += pVariables[i].pType->PackedSize;
1025     }
1026
1027     pDesc->UnpackedSize = Size;
1028     D3DXASSERT(pDesc->UnpackedSize >= pDesc->PackedSize);
1029
1030     pDesc->Stride = AlignToPowerOf2(pDesc->UnpackedSize, SType::c_RegisterSize);
1031
1032     return S_OK;
1033 }
1034
1035 ID3DX11EffectType * SConstantBuffer::GetMemberTypeByIndex(UINT  Index)
1036 {
1037     return GetTypeByIndexHelper(Index, VariableCount, pVariables, sizeof (SGlobalVariable));
1038 }
1039
1040 ID3DX11EffectType * SConstantBuffer::GetMemberTypeByName(LPCSTR Name)
1041 {
1042     return GetTypeByNameHelper(Name, VariableCount, pVariables, sizeof (SGlobalVariable));
1043 }
1044
1045 ID3DX11EffectType * SConstantBuffer::GetMemberTypeBySemantic(LPCSTR Semantic)
1046 {
1047     return GetTypeBySemanticHelper(Semantic, VariableCount, pVariables, sizeof (SGlobalVariable));
1048 }
1049
1050 LPCSTR SConstantBuffer::GetMemberName(UINT Index)
1051 {
1052     LPCSTR pFuncName = "ID3DX11EffectType::GetMemberName";
1053
1054     if (IsEffectOptimized)
1055     {
1056         DPF(0, "%s: Cannot get member names; Effect has been Optimize()'ed", pFuncName);
1057         return NULL;
1058     }
1059
1060     if (Index >= VariableCount)
1061     {
1062         DPF(0, "%s: Invalid index (%d, total: %d)", pFuncName, Index, VariableCount);
1063         return NULL;
1064     }
1065
1066     return pVariables[Index].pName;
1067 }
1068
1069 LPCSTR SConstantBuffer::GetMemberSemantic(UINT Index)
1070 {
1071     LPCSTR pFuncName = "ID3DX11EffectType::GetMemberSemantic";
1072
1073     if (IsEffectOptimized)
1074     {
1075         DPF(0, "%s: Cannot get member semantics; Effect has been Optimize()'ed", pFuncName);
1076         return NULL;
1077     }
1078
1079     if (Index >= VariableCount)
1080     {
1081         DPF(0, "%s: Invalid index (%d, total: %d)", pFuncName, Index, VariableCount);
1082         return NULL;
1083     }
1084
1085     return pVariables[Index].pSemantic;
1086 }
1087
1088 HRESULT SConstantBuffer::SetRawValue(CONST void *pData, UINT  Offset, UINT  Count)
1089 {
1090     HRESULT hr = S_OK;    
1091
1092 #ifdef _DEBUG
1093     LPCSTR pFuncName = "ID3DX11EffectVariable::SetRawValue";
1094
1095     VERIFYPARAMETER(pData);
1096
1097     if ((Offset + Count < Offset) ||
1098         (Count + (BYTE*)pData < (BYTE*)pData) ||
1099         ((Offset + Count) > Size))
1100     {
1101         // overflow of some kind
1102         DPF(0, "%s: Invalid range specified", pFuncName);
1103         VH(E_INVALIDARG);
1104     }
1105 #endif
1106
1107     if (IsUsedByExpression)
1108     {
1109         UINT  i;
1110         for (i = 0; i < VariableCount; ++ i)
1111         {
1112             ((SGlobalVariable*)pVariables)[i].DirtyVariable();
1113         }
1114     }
1115     else
1116     {
1117         IsDirty = TRUE;
1118     }
1119
1120     memcpy(pBackingStore + Offset, pData, Count);
1121
1122 lExit:
1123     return hr;
1124 }
1125
1126 HRESULT SConstantBuffer::GetRawValue(__out_bcount(Count) void *pData, UINT  Offset, UINT  Count)
1127 {
1128     HRESULT hr = S_OK;    
1129
1130 #ifdef _DEBUG
1131     LPCSTR pFuncName = "ID3DX11EffectVariable::GetRawValue";
1132
1133     VERIFYPARAMETER(pData);
1134
1135     if ((Offset + Count < Offset) ||
1136         (Count + (BYTE*)pData < (BYTE*)pData) ||
1137         ((Offset + Count) > Size))
1138     {
1139         // overflow of some kind
1140         DPF(0, "%s: Invalid range specified", pFuncName);
1141         VH(E_INVALIDARG);
1142     }
1143 #endif
1144
1145     memcpy(pData, pBackingStore + Offset, Count);
1146
1147 lExit:
1148     return hr;
1149 }
1150
1151 bool SConstantBuffer::ClonedSingle() const
1152 {
1153     return IsSingle && ( pEffect->m_Flags & D3DX11_EFFECT_CLONE );
1154 }
1155
1156 HRESULT SConstantBuffer::SetConstantBuffer(ID3D11Buffer *pConstantBuffer)
1157 {
1158     HRESULT hr = S_OK;
1159     LPCSTR pFuncName = "ID3DX11EffectConstantBuffer::SetConstantBuffer";
1160
1161     if (IsTBuffer)
1162     {
1163         DPF(0, "%s: This is a texture buffer; use SetTextureBuffer instead", pFuncName);
1164         VH(D3DERR_INVALIDCALL);
1165     }
1166
1167     // Replace all references to the old shader block with this one
1168     pEffect->ReplaceCBReference(this, pConstantBuffer);
1169
1170     if( !IsUserManaged )
1171     {
1172         // Save original cbuffer in case we UndoSet
1173         D3DXASSERT( pMemberData[0].Type == MDT_Buffer );
1174         VB( pMemberData[0].Data.pD3DEffectsManagedConstantBuffer == NULL );
1175         pMemberData[0].Data.pD3DEffectsManagedConstantBuffer = pD3DObject;
1176         pD3DObject = NULL;
1177         IsUserManaged = TRUE;
1178         IsNonUpdatable = TRUE;
1179     }
1180
1181     SAFE_ADDREF( pConstantBuffer );
1182     SAFE_RELEASE( pD3DObject );
1183     pD3DObject = pConstantBuffer;
1184
1185 lExit:
1186     return hr;
1187 }
1188
1189 HRESULT SConstantBuffer::GetConstantBuffer(ID3D11Buffer **ppConstantBuffer)
1190 {
1191     HRESULT hr = S_OK;
1192     LPCSTR pFuncName = "ID3DX11EffectConstantBuffer::GetConstantBuffer";
1193
1194     VERIFYPARAMETER(ppConstantBuffer);
1195
1196     if (IsTBuffer)
1197     {
1198         DPF(0, "%s: This is a texture buffer; use GetTextureBuffer instead", pFuncName);
1199         VH(D3DERR_INVALIDCALL);
1200     }
1201
1202     *ppConstantBuffer = pD3DObject;
1203     SAFE_ADDREF(*ppConstantBuffer);
1204
1205 lExit:
1206     return hr;
1207 }
1208
1209 HRESULT SConstantBuffer::UndoSetConstantBuffer() 
1210 {
1211     HRESULT hr = S_OK;
1212     LPCSTR pFuncName = "ID3DX11EffectConstantBuffer::UndoSetConstantBuffer";
1213
1214     if (IsTBuffer)
1215     {
1216         DPF(0, "%s: This is a texture buffer; use UndoSetTextureBuffer instead", pFuncName);
1217         VH(D3DERR_INVALIDCALL);
1218     }
1219
1220     if( !IsUserManaged )
1221     {
1222         return S_FALSE;
1223     }
1224
1225     // Replace all references to the old shader block with this one
1226     pEffect->ReplaceCBReference(this, pMemberData[0].Data.pD3DEffectsManagedConstantBuffer);
1227
1228     // Revert to original cbuffer
1229     SAFE_RELEASE( pD3DObject );
1230     pD3DObject = pMemberData[0].Data.pD3DEffectsManagedConstantBuffer;
1231     pMemberData[0].Data.pD3DEffectsManagedConstantBuffer = NULL;
1232     IsUserManaged = FALSE;
1233     IsNonUpdatable = ClonedSingle();
1234
1235 lExit:
1236     return hr;
1237 }
1238
1239 HRESULT SConstantBuffer::SetTextureBuffer(ID3D11ShaderResourceView *pTextureBuffer)
1240 {
1241     HRESULT hr = S_OK;
1242     LPCSTR pFuncName = "ID3DX11EffectConstantBuffer::SetTextureBuffer";
1243
1244     if (!IsTBuffer)
1245     {
1246         DPF(0, "%s: This is a constant buffer; use SetConstantBuffer instead", pFuncName);
1247         VH(D3DERR_INVALIDCALL);
1248     }
1249
1250     if( !IsUserManaged )
1251     {
1252         // Save original cbuffer and tbuffer in case we UndoSet
1253         D3DXASSERT( pMemberData[0].Type == MDT_Buffer );
1254         VB( pMemberData[0].Data.pD3DEffectsManagedConstantBuffer == NULL );
1255         pMemberData[0].Data.pD3DEffectsManagedConstantBuffer = pD3DObject;
1256         pD3DObject = NULL;
1257         D3DXASSERT( pMemberData[1].Type == MDT_ShaderResourceView );
1258         VB( pMemberData[1].Data.pD3DEffectsManagedTextureBuffer == NULL );
1259         pMemberData[1].Data.pD3DEffectsManagedTextureBuffer = TBuffer.pShaderResource;
1260         TBuffer.pShaderResource = NULL;
1261         IsUserManaged = TRUE;
1262         IsNonUpdatable = TRUE;
1263     }
1264
1265     SAFE_ADDREF( pTextureBuffer );
1266     SAFE_RELEASE(pD3DObject); // won't be needing this anymore...
1267     SAFE_RELEASE( TBuffer.pShaderResource );
1268     TBuffer.pShaderResource = pTextureBuffer;
1269
1270 lExit:
1271     return hr;
1272 }
1273
1274 HRESULT SConstantBuffer::GetTextureBuffer(ID3D11ShaderResourceView **ppTextureBuffer)
1275 {
1276     HRESULT hr = S_OK;
1277     LPCSTR pFuncName = "ID3DX11EffectConstantBuffer::GetTextureBuffer";
1278
1279     VERIFYPARAMETER(ppTextureBuffer);
1280
1281     if (!IsTBuffer)
1282     {
1283         DPF(0, "%s: This is a constant buffer; use GetConstantBuffer instead", pFuncName);
1284         VH(D3DERR_INVALIDCALL);
1285     }
1286
1287     *ppTextureBuffer = TBuffer.pShaderResource;
1288     SAFE_ADDREF(*ppTextureBuffer);
1289
1290 lExit:
1291     return hr;
1292 }
1293
1294 HRESULT SConstantBuffer::UndoSetTextureBuffer()
1295 {
1296     HRESULT hr = S_OK;
1297     LPCSTR pFuncName = "ID3DX11EffectConstantBuffer::UndoSetTextureBuffer";
1298
1299     if (!IsTBuffer)
1300     {
1301         DPF(0, "%s: This is a texture buffer; use UndoSetConstantBuffer instead", pFuncName);
1302         VH(D3DERR_INVALIDCALL);
1303     }
1304
1305     if( !IsUserManaged )
1306     {
1307         return S_FALSE;
1308     }
1309
1310     // Revert to original cbuffer
1311     SAFE_RELEASE( pD3DObject );
1312     pD3DObject = pMemberData[0].Data.pD3DEffectsManagedConstantBuffer;
1313     pMemberData[0].Data.pD3DEffectsManagedConstantBuffer = NULL;
1314     SAFE_RELEASE( TBuffer.pShaderResource );
1315     TBuffer.pShaderResource = pMemberData[1].Data.pD3DEffectsManagedTextureBuffer;
1316     pMemberData[1].Data.pD3DEffectsManagedTextureBuffer = NULL;
1317     IsUserManaged = FALSE;
1318     IsNonUpdatable = ClonedSingle();
1319
1320 lExit:
1321     return hr;
1322 }
1323
1324 //////////////////////////////////////////////////////////////////////////
1325 // ID3DX11EffectPass (CEffectPass implementation)
1326 //////////////////////////////////////////////////////////////////////////
1327
1328 BOOL SPassBlock::IsValid()
1329 {
1330     if( HasDependencies )
1331         return pEffect->ValidatePassBlock( this );
1332     return InitiallyValid;
1333 }
1334
1335 HRESULT SPassBlock::GetDesc(D3DX11_PASS_DESC *pDesc)
1336 {
1337     HRESULT hr = S_OK;
1338     LPCSTR pFuncName = "ID3DX11EffectPass::GetDesc";
1339
1340     VERIFYPARAMETER(pDesc);
1341
1342     ZeroMemory(pDesc, sizeof(*pDesc));
1343
1344     pDesc->Name = pName;
1345     pDesc->Annotations = AnnotationCount;
1346     
1347     SAssignment *pAssignment;
1348     SAssignment *pLastAssn;
1349
1350     pEffect->IncrementTimer();
1351
1352     pAssignment = pAssignments;
1353     pLastAssn = pAssignments + AssignmentCount;
1354
1355     for(; pAssignment < pLastAssn; pAssignment++)
1356     {
1357         pEffect->EvaluateAssignment(pAssignment);
1358     }
1359
1360     if( BackingStore.pVertexShaderBlock && BackingStore.pVertexShaderBlock->pInputSignatureBlob )
1361     {
1362         // pInputSignatureBlob can be null if we're setting a NULL VS "SetVertexShader( NULL )"
1363         pDesc->pIAInputSignature = (BYTE*)BackingStore.pVertexShaderBlock->pInputSignatureBlob->GetBufferPointer();
1364         pDesc->IAInputSignatureSize = BackingStore.pVertexShaderBlock->pInputSignatureBlob->GetBufferSize();
1365     }
1366
1367     pDesc->StencilRef = BackingStore.StencilRef;
1368     pDesc->SampleMask = BackingStore.SampleMask;
1369     pDesc->BlendFactor[0] = BackingStore.BlendFactor[0];
1370     pDesc->BlendFactor[1] = BackingStore.BlendFactor[1];
1371     pDesc->BlendFactor[2] = BackingStore.BlendFactor[2];
1372     pDesc->BlendFactor[3] = BackingStore.BlendFactor[3];
1373
1374 lExit:
1375     return hr;
1376 }
1377
1378 extern SShaderBlock g_NullVS;
1379 extern SShaderBlock g_NullGS;
1380 extern SShaderBlock g_NullPS;
1381 extern SShaderBlock g_NullHS;
1382 extern SShaderBlock g_NullDS;
1383 extern SShaderBlock g_NullCS;
1384
1385 SAnonymousShader g_AnonymousNullVS(&g_NullVS);
1386 SAnonymousShader g_AnonymousNullGS(&g_NullGS);
1387 SAnonymousShader g_AnonymousNullPS(&g_NullPS);
1388 SAnonymousShader g_AnonymousNullHS(&g_NullHS);
1389 SAnonymousShader g_AnonymousNullDS(&g_NullDS);
1390 SAnonymousShader g_AnonymousNullCS(&g_NullCS);
1391
1392 template<EObjectType EShaderType>
1393 HRESULT SPassBlock::GetShaderDescHelper(D3DX11_PASS_SHADER_DESC *pDesc)
1394 {
1395     HRESULT hr = S_OK;
1396     UINT  i;
1397     LPCSTR pFuncName = NULL;
1398     SShaderBlock *pShaderBlock = NULL;
1399
1400     ApplyPassAssignments();
1401
1402     switch (EShaderType)
1403     {
1404     case EOT_VertexShader:
1405     case EOT_VertexShader5:
1406 #pragma prefast(suppress:__WARNING_UNUSED_POINTER_ASSIGNMENT, "pFuncName used in DPF")
1407         pFuncName = "ID3DX11EffectPass::GetVertexShaderDesc";
1408         pShaderBlock = BackingStore.pVertexShaderBlock;
1409         break;
1410     case EOT_PixelShader:
1411     case EOT_PixelShader5:
1412 #pragma prefast(suppress:__WARNING_UNUSED_POINTER_ASSIGNMENT, "pFuncName used in DPF")
1413         pFuncName = "ID3DX11EffectPass::GetPixelShaderDesc";
1414         pShaderBlock = BackingStore.pPixelShaderBlock;
1415         break;
1416     case EOT_GeometryShader:
1417     case EOT_GeometryShader5:
1418 #pragma prefast(suppress:__WARNING_UNUSED_POINTER_ASSIGNMENT, "pFuncName used in DPF")
1419         pFuncName = "ID3DX11EffectPass::GetGeometryShaderDesc";
1420         pShaderBlock = BackingStore.pGeometryShaderBlock;
1421         break;
1422     case EOT_HullShader5:
1423 #pragma prefast(suppress:__WARNING_UNUSED_POINTER_ASSIGNMENT, "pFuncName used in DPF")
1424         pFuncName = "ID3DX11EffectPass::GetHullShaderDesc";
1425         pShaderBlock = BackingStore.pHullShaderBlock;
1426         break;
1427     case EOT_DomainShader5:
1428 #pragma prefast(suppress:__WARNING_UNUSED_POINTER_ASSIGNMENT, "pFuncName used in DPF")
1429         pFuncName = "ID3DX11EffectPass::GetDomainShaderDesc";
1430         pShaderBlock = BackingStore.pDomainShaderBlock;
1431         break;
1432     case EOT_ComputeShader5:
1433 #pragma prefast(suppress:__WARNING_UNUSED_POINTER_ASSIGNMENT, "pFuncName used in DPF")
1434         pFuncName = "ID3DX11EffectPass::GetComputeShaderDesc";
1435         pShaderBlock = BackingStore.pComputeShaderBlock;
1436         break;
1437     default:
1438         D3DXASSERT(0);
1439     }
1440
1441     VERIFYPARAMETER(pDesc);
1442
1443     // in case of error (or in case the assignment doesn't exist), return something reasonable
1444     pDesc->pShaderVariable = &g_InvalidShaderVariable;
1445     pDesc->ShaderIndex = 0;
1446
1447     if (NULL != pShaderBlock)
1448     {
1449         UINT elements, varCount, anonymousShaderCount;
1450         SGlobalVariable *pVariables;
1451         SAnonymousShader *pAnonymousShaders;
1452
1453         if (pShaderBlock == &g_NullVS)
1454         {
1455             pDesc->pShaderVariable = &g_AnonymousNullVS;
1456             pDesc->ShaderIndex = 0;
1457             // we're done
1458             goto lExit;
1459         }
1460         else if (pShaderBlock == &g_NullGS)
1461         {
1462             pDesc->pShaderVariable = &g_AnonymousNullGS;
1463             pDesc->ShaderIndex = 0;
1464             // we're done
1465             goto lExit;
1466         }
1467         else if (pShaderBlock == &g_NullPS)
1468         {
1469             pDesc->pShaderVariable = &g_AnonymousNullPS;
1470             pDesc->ShaderIndex = 0;
1471             // we're done
1472             goto lExit;
1473         }
1474         else if (pShaderBlock == &g_NullHS)
1475         {
1476             pDesc->pShaderVariable = &g_AnonymousNullHS;
1477             pDesc->ShaderIndex = 0;
1478             // we're done
1479             goto lExit;
1480         }
1481         else if (pShaderBlock == &g_NullDS)
1482         {
1483             pDesc->pShaderVariable = &g_AnonymousNullDS;
1484             pDesc->ShaderIndex = 0;
1485             // we're done
1486             goto lExit;
1487         }
1488         else if (pShaderBlock == &g_NullCS)
1489         {
1490             pDesc->pShaderVariable = &g_AnonymousNullCS;
1491             pDesc->ShaderIndex = 0;
1492             // we're done
1493             goto lExit;
1494         }
1495         else 
1496         {
1497             VB( pEffect->IsRuntimeData(pShaderBlock) );
1498             varCount = pEffect->m_VariableCount;
1499             pVariables = pEffect->m_pVariables;
1500             anonymousShaderCount = pEffect->m_AnonymousShaderCount;
1501             pAnonymousShaders = pEffect->m_pAnonymousShaders;
1502         }
1503
1504         for (i = 0; i < varCount; ++ i)
1505         {
1506             elements = max(1, pVariables[i].pType->Elements);
1507             // make sure the variable type matches, and don't forget about GeometryShaderSO's
1508             if (pVariables[i].pType->IsShader())
1509             {
1510                 if (pShaderBlock >= pVariables[i].Data.pShader && pShaderBlock < pVariables[i].Data.pShader + elements)
1511                 {
1512                     pDesc->pShaderVariable = (ID3DX11EffectShaderVariable *)(pVariables + i);
1513                     pDesc->ShaderIndex = (UINT)(UINT_PTR)(pShaderBlock - pVariables[i].Data.pShader);
1514                     // we're done
1515                     goto lExit;
1516                 }
1517             }
1518         }
1519
1520         for (i = 0; i < anonymousShaderCount; ++ i)
1521         {
1522             if (pShaderBlock == pAnonymousShaders[i].pShaderBlock)
1523             {
1524                 VB(EShaderType == pAnonymousShaders[i].pShaderBlock->GetShaderType())
1525                 pDesc->pShaderVariable = (pAnonymousShaders + i);
1526                 pDesc->ShaderIndex = 0;
1527                 // we're done
1528                 goto lExit;
1529             }
1530         }
1531
1532         DPF(0, "%s: Internal error; shader not found", pFuncName);
1533         VH( E_FAIL );
1534     }
1535
1536 lExit:
1537     return hr;
1538 }
1539
1540 HRESULT SPassBlock::GetVertexShaderDesc(D3DX11_PASS_SHADER_DESC *pDesc)
1541 {
1542     return GetShaderDescHelper<EOT_VertexShader>(pDesc);
1543 }
1544
1545 HRESULT SPassBlock::GetPixelShaderDesc(D3DX11_PASS_SHADER_DESC *pDesc)
1546 {
1547     return GetShaderDescHelper<EOT_PixelShader>(pDesc);
1548 }
1549
1550 HRESULT SPassBlock::GetGeometryShaderDesc(D3DX11_PASS_SHADER_DESC *pDesc)
1551 {
1552     return GetShaderDescHelper<EOT_GeometryShader>(pDesc);
1553 }
1554
1555 HRESULT SPassBlock::GetHullShaderDesc(D3DX11_PASS_SHADER_DESC *pDesc)
1556 {
1557     return GetShaderDescHelper<EOT_HullShader5>(pDesc);
1558 }
1559
1560 HRESULT SPassBlock::GetDomainShaderDesc(D3DX11_PASS_SHADER_DESC *pDesc)
1561 {
1562     return GetShaderDescHelper<EOT_DomainShader5>(pDesc);
1563 }
1564
1565 HRESULT SPassBlock::GetComputeShaderDesc(D3DX11_PASS_SHADER_DESC *pDesc)
1566 {
1567     return GetShaderDescHelper<EOT_ComputeShader5>(pDesc);
1568 }
1569
1570 ID3DX11EffectVariable * SPassBlock::GetAnnotationByIndex(UINT  Index)
1571 {
1572     return GetAnnotationByIndexHelper("ID3DX11EffectPass", Index, AnnotationCount, pAnnotations);
1573 }
1574
1575 ID3DX11EffectVariable * SPassBlock::GetAnnotationByName(LPCSTR Name)
1576 {
1577     return GetAnnotationByNameHelper("ID3DX11EffectPass", Name, AnnotationCount, pAnnotations);
1578 }
1579
1580 HRESULT SPassBlock::Apply(UINT  Flags, ID3D11DeviceContext* pContext)
1581 {
1582     HRESULT hr = S_OK;
1583
1584     // TODO: Flags are not yet implemented    
1585
1586     D3DXASSERT( pEffect->m_pContext == NULL );
1587     pEffect->m_pContext = pContext;
1588     pEffect->ApplyPassBlock(this);
1589     pEffect->m_pContext = NULL;
1590
1591 lExit:
1592     return hr;
1593 }
1594
1595 HRESULT SPassBlock::ComputeStateBlockMask(D3DX11_STATE_BLOCK_MASK *pStateBlockMask)
1596 {
1597     HRESULT hr = S_OK;
1598     UINT i, j;
1599     
1600     // flags indicating whether the following shader types were caught by assignment checks or not
1601     BOOL bVS = FALSE, bGS = FALSE, bPS = FALSE, bHS = FALSE, bDS = FALSE, bCS = FALSE;
1602
1603     for (i = 0; i < AssignmentCount; ++ i)
1604     {
1605         BOOL bShader = FALSE;
1606         
1607         switch (pAssignments[i].LhsType)
1608         {
1609         case ELHS_VertexShaderBlock:
1610             bVS = TRUE;
1611             bShader = TRUE;
1612             break;
1613         case ELHS_GeometryShaderBlock:
1614             bGS = TRUE;
1615             bShader = TRUE;
1616             break;
1617         case ELHS_PixelShaderBlock:
1618             bPS = TRUE;
1619             bShader = TRUE;
1620             break;
1621         case ELHS_HullShaderBlock:
1622             bHS = TRUE;
1623             bShader = TRUE;
1624             break;
1625         case ELHS_DomainShaderBlock:
1626             bDS = TRUE;
1627             bShader = TRUE;
1628             break;
1629         case ELHS_ComputeShaderBlock:
1630             bCS = TRUE;
1631             bShader = TRUE;
1632             break;
1633
1634         case ELHS_RasterizerBlock:
1635             pStateBlockMask->RSRasterizerState = 1;
1636             break;
1637         case ELHS_BlendBlock:
1638             pStateBlockMask->OMBlendState = 1;
1639             break;
1640         case ELHS_DepthStencilBlock:
1641             pStateBlockMask->OMDepthStencilState = 1;
1642             break;
1643
1644         default:            
1645             // ignore this assignment (must be a scalar/vector assignment associated with a state object)
1646             break;
1647         }
1648
1649         if (bShader)
1650         {
1651             for (j = 0; j < pAssignments[i].MaxElements; ++ j)
1652             {
1653                 // compute state block mask for the union of ALL shaders
1654                 VH( pAssignments[i].Source.pShader[j].ComputeStateBlockMask(pStateBlockMask) );
1655             }
1656         }
1657     }
1658
1659     // go over the state block objects in case there was no corresponding assignment
1660     if (NULL != BackingStore.pRasterizerBlock)
1661     {
1662         pStateBlockMask->RSRasterizerState = 1;
1663     }
1664     if (NULL != BackingStore.pBlendBlock)
1665     {
1666         pStateBlockMask->OMBlendState = 1;
1667     }
1668     if (NULL != BackingStore.pDepthStencilBlock)
1669     {
1670         pStateBlockMask->OMDepthStencilState = 1;
1671     }
1672
1673     // go over the shaders only if an assignment didn't already catch them
1674     if (FALSE == bVS && NULL != BackingStore.pVertexShaderBlock)
1675     {
1676         VH( BackingStore.pVertexShaderBlock->ComputeStateBlockMask(pStateBlockMask) );
1677     }
1678     if (FALSE == bGS && NULL != BackingStore.pGeometryShaderBlock)
1679     {
1680         VH( BackingStore.pGeometryShaderBlock->ComputeStateBlockMask(pStateBlockMask) );
1681     }
1682     if (FALSE == bPS && NULL != BackingStore.pPixelShaderBlock)
1683     {
1684         VH( BackingStore.pPixelShaderBlock->ComputeStateBlockMask(pStateBlockMask) );
1685     }
1686     if (FALSE == bHS && NULL != BackingStore.pHullShaderBlock)
1687     {
1688         VH( BackingStore.pHullShaderBlock->ComputeStateBlockMask(pStateBlockMask) );
1689     }
1690     if (FALSE == bDS && NULL != BackingStore.pDomainShaderBlock)
1691     {
1692         VH( BackingStore.pDomainShaderBlock->ComputeStateBlockMask(pStateBlockMask) );
1693     }
1694     if (FALSE == bCS && NULL != BackingStore.pComputeShaderBlock)
1695     {
1696         VH( BackingStore.pComputeShaderBlock->ComputeStateBlockMask(pStateBlockMask) );
1697     }
1698     
1699 lExit:
1700     return hr;
1701 }
1702
1703 //////////////////////////////////////////////////////////////////////////
1704 // ID3DX11EffectTechnique (STechnique implementation)
1705 //////////////////////////////////////////////////////////////////////////
1706
1707 BOOL STechnique::IsValid()
1708
1709     if( HasDependencies )
1710     {
1711         for( UINT i = 0; i < PassCount; i++ )
1712         {
1713             if( !((SPassBlock*)pPasses)[i].IsValid() )
1714                 return FALSE;
1715         }
1716         return TRUE;
1717     }
1718     return InitiallyValid;
1719 }
1720
1721 HRESULT STechnique::GetDesc(D3DX11_TECHNIQUE_DESC *pDesc)
1722 {
1723     HRESULT hr = S_OK;
1724
1725     LPCSTR pFuncName = "ID3DX11EffectTechnique::GetDesc";
1726
1727     VERIFYPARAMETER(pDesc);
1728
1729     pDesc->Name = pName;
1730     pDesc->Annotations = AnnotationCount;
1731     pDesc->Passes = PassCount;
1732
1733 lExit:
1734     return hr;
1735 }
1736
1737 ID3DX11EffectVariable * STechnique::GetAnnotationByIndex(UINT  Index)
1738 {
1739     return GetAnnotationByIndexHelper("ID3DX11EffectTechnique", Index, AnnotationCount, pAnnotations);
1740 }
1741
1742 ID3DX11EffectVariable * STechnique::GetAnnotationByName(LPCSTR Name)
1743 {
1744     return GetAnnotationByNameHelper("ID3DX11EffectTechnique", Name, AnnotationCount, pAnnotations);
1745 }
1746
1747 ID3DX11EffectPass * STechnique::GetPassByIndex(UINT  Index)
1748 {
1749     LPCSTR pFuncName = "ID3DX11EffectTechnique::GetPassByIndex";
1750
1751     if (Index >= PassCount)
1752     {
1753         DPF(0, "%s: Invalid pass index (%d, total: %d)", pFuncName, Index, PassCount);
1754         return &g_InvalidPass;
1755     }
1756
1757     return (ID3DX11EffectPass *)(pPasses + Index);
1758 }
1759
1760 ID3DX11EffectPass * STechnique::GetPassByName(LPCSTR Name)
1761 {
1762     LPCSTR pFuncName = "ID3DX11EffectTechnique::GetPassByName";
1763
1764     UINT  i;
1765
1766     for (i = 0; i < PassCount; ++ i)
1767     {
1768         if (NULL != pPasses[i].pName &&
1769             strcmp(pPasses[i].pName, Name) == 0)
1770         {
1771             break;
1772         }
1773     }
1774
1775     if (i == PassCount)
1776     {
1777         DPF(0, "%s: Pass [%s] not found", pFuncName, Name);
1778         return &g_InvalidPass;
1779     }
1780
1781     return (ID3DX11EffectPass *)(pPasses + i);
1782 }
1783
1784 HRESULT STechnique::ComputeStateBlockMask(D3DX11_STATE_BLOCK_MASK *pStateBlockMask)
1785 {
1786     HRESULT hr = S_OK;
1787     UINT i;
1788
1789     for (i = 0; i < PassCount; ++ i)
1790     {
1791         VH( ((SPassBlock*)pPasses)[i].ComputeStateBlockMask(pStateBlockMask) );
1792     }
1793
1794 lExit:
1795     return hr;
1796 }
1797
1798 //////////////////////////////////////////////////////////////////////////
1799 // ID3DX11EffectGroup (SGroup implementation)
1800 //////////////////////////////////////////////////////////////////////////
1801
1802 BOOL SGroup::IsValid()
1803
1804     if( HasDependencies )
1805     {
1806         for( UINT i = 0; i < TechniqueCount; i++ )
1807         {
1808             if( !((STechnique*)pTechniques)[i].IsValid() )
1809                 return FALSE;
1810         }
1811         return TRUE;
1812     }
1813     return InitiallyValid;
1814 }
1815
1816 HRESULT SGroup::GetDesc(D3DX11_GROUP_DESC *pDesc)
1817 {
1818     HRESULT hr = S_OK;
1819
1820     LPCSTR pFuncName = "ID3DX11EffectGroup::GetDesc";
1821
1822     VERIFYPARAMETER(pDesc);
1823
1824     pDesc->Name = pName;
1825     pDesc->Annotations = AnnotationCount;
1826     pDesc->Techniques = TechniqueCount;
1827
1828 lExit:
1829     return hr;
1830 }
1831
1832 ID3DX11EffectVariable * SGroup::GetAnnotationByIndex(UINT  Index)
1833 {
1834     return GetAnnotationByIndexHelper("ID3DX11EffectGroup", Index, AnnotationCount, pAnnotations);
1835 }
1836
1837 ID3DX11EffectVariable * SGroup::GetAnnotationByName(LPCSTR Name)
1838 {
1839     return GetAnnotationByNameHelper("ID3DX11EffectGroup", Name, AnnotationCount, pAnnotations);
1840 }
1841
1842 ID3DX11EffectTechnique * SGroup::GetTechniqueByIndex(UINT  Index)
1843 {
1844     LPCSTR pFuncName = "ID3DX11EffectGroup::GetTechniqueByIndex";
1845
1846     if (Index >= TechniqueCount)
1847     {
1848         DPF(0, "%s: Invalid pass index (%d, total: %d)", pFuncName, Index, TechniqueCount);
1849         return &g_InvalidTechnique;
1850     }
1851
1852     return (ID3DX11EffectTechnique *)(pTechniques + Index);
1853 }
1854
1855 ID3DX11EffectTechnique * SGroup::GetTechniqueByName(LPCSTR Name)
1856 {
1857     LPCSTR pFuncName = "ID3DX11EffectGroup::GetTechniqueByName";
1858
1859     UINT  i;
1860
1861     for (i = 0; i < TechniqueCount; ++ i)
1862     {
1863         if (NULL != pTechniques[i].pName &&
1864             strcmp(pTechniques[i].pName, Name) == 0)
1865         {
1866             break;
1867         }
1868     }
1869
1870     if (i == TechniqueCount)
1871     {
1872         DPF(0, "%s: Technique [%s] not found", pFuncName, Name);
1873         return &g_InvalidTechnique;
1874     }
1875
1876     return (ID3DX11EffectTechnique *)(pTechniques + i);
1877 }
1878
1879 //////////////////////////////////////////////////////////////////////////
1880 // ID3DX11Effect Public Reflection APIs (CEffect)
1881 //////////////////////////////////////////////////////////////////////////
1882
1883 HRESULT CEffect::GetDevice(ID3D11Device **ppDevice)
1884 {
1885     HRESULT hr = S_OK;
1886     LPCSTR pFuncName = "ID3DX11Effect::GetDevice";
1887     VERIFYPARAMETER(ppDevice);
1888
1889     m_pDevice->AddRef();
1890     *ppDevice = m_pDevice;
1891
1892 lExit:
1893     return hr;
1894 }
1895
1896 HRESULT CEffect::GetDesc(D3DX11_EFFECT_DESC *pDesc)
1897 {
1898     HRESULT hr = S_OK;
1899
1900     LPCSTR pFuncName = "ID3DX11Effect::GetDesc";
1901
1902     VERIFYPARAMETER(pDesc);
1903
1904     pDesc->ConstantBuffers = m_CBCount;
1905     pDesc->GlobalVariables = m_VariableCount;
1906     pDesc->Techniques = m_TechniqueCount;
1907     pDesc->Groups = m_GroupCount;
1908     pDesc->InterfaceVariables = m_InterfaceCount;
1909
1910 lExit:
1911     return hr;    
1912 }
1913
1914 ID3DX11EffectConstantBuffer * CEffect::GetConstantBufferByIndex(UINT  Index)
1915 {
1916     LPCSTR pFuncName = "ID3DX11Effect::GetConstantBufferByIndex";
1917
1918     if (Index < m_CBCount)
1919     {
1920         return m_pCBs + Index;
1921     }
1922
1923     DPF(0, "%s: Invalid constant buffer index", pFuncName);
1924     return &g_InvalidConstantBuffer;
1925 }
1926
1927 ID3DX11EffectConstantBuffer * CEffect::GetConstantBufferByName(LPCSTR Name)
1928 {
1929     HRESULT hr = S_OK;
1930     LPCSTR pFuncName = "ID3DX11Effect::GetConstantBufferByName";
1931
1932     if (IsOptimized())
1933     {
1934         DPF(0, "%s: Cannot get constant buffer interfaces by name since the effect has been Optimize()'ed", pFuncName);
1935         return &g_InvalidConstantBuffer;
1936     }
1937
1938     if (NULL == Name)
1939     {
1940         DPF(0, "%s: Parameter Name was NULL.", pFuncName);
1941         return &g_InvalidConstantBuffer;
1942     }
1943
1944     UINT  i;
1945
1946     for (i = 0; i < m_CBCount; ++ i)
1947     {
1948         if (strcmp(m_pCBs[i].pName, Name) == 0)
1949         {
1950             return m_pCBs + i;
1951         }
1952     }
1953
1954     DPF(0, "%s: Constant Buffer [%s] not found", pFuncName, Name);
1955     return &g_InvalidConstantBuffer;
1956 }
1957
1958 ID3DX11EffectVariable * CEffect::GetVariableByIndex(UINT  Index)
1959 {
1960     LPCSTR pFuncName = "ID3DX11Effect::GetVariableByIndex";
1961
1962     if (Index < m_VariableCount)
1963     {
1964         return m_pVariables + Index;
1965     }
1966
1967     DPF(0, "%s: Invalid variable index", pFuncName);
1968     return &g_InvalidScalarVariable;
1969 }
1970
1971 ID3DX11EffectVariable * CEffect::GetVariableByName(LPCSTR Name)
1972 {
1973     HRESULT hr = S_OK;
1974     LPCSTR pFuncName = "ID3DX11Effect::GetVariableByName";
1975
1976     if (IsOptimized())
1977     {
1978         DPF(0, "%s: Cannot get variable interfaces by name since the effect has been Optimize()'ed", pFuncName);
1979         return &g_InvalidScalarVariable;
1980     }
1981
1982     if (NULL == Name)
1983     {
1984         DPF(0, "%s: Parameter Name was NULL.", pFuncName);
1985         return &g_InvalidScalarVariable;
1986     }
1987
1988     UINT  i;
1989
1990     for (i = 0; i < m_VariableCount; ++ i)
1991     {
1992         if (strcmp(m_pVariables[i].pName, Name) == 0)
1993         {
1994             return m_pVariables + i;
1995         }
1996     }
1997
1998     DPF(0, "%s: Variable [%s] not found", pFuncName, Name);
1999     return &g_InvalidScalarVariable;
2000 }
2001
2002 ID3DX11EffectVariable * CEffect::GetVariableBySemantic(LPCSTR Semantic)
2003 {    
2004     LPCSTR pFuncName = "ID3DX11Effect::GetVariableBySemantic";
2005
2006     if (IsOptimized())
2007     {
2008         DPF(0, "%s: Cannot get variable interfaces by semantic since the effect has been Optimize()'ed", pFuncName);
2009         return &g_InvalidScalarVariable;
2010     }
2011
2012     if (NULL == Semantic)
2013     {
2014         DPF(0, "%s: Parameter Semantic was NULL.", pFuncName);
2015         return &g_InvalidScalarVariable;
2016     }
2017
2018     UINT  i;
2019
2020     for (i = 0; i < m_VariableCount; ++ i)
2021     {
2022         if (NULL != m_pVariables[i].pSemantic && 
2023             _stricmp(m_pVariables[i].pSemantic, Semantic) == 0)
2024         {
2025             return (ID3DX11EffectVariable *)(m_pVariables + i);
2026         }
2027     }
2028
2029     DPF(0, "%s: Variable with semantic [%s] not found", pFuncName, Semantic);
2030     return &g_InvalidScalarVariable;
2031 }
2032
2033 ID3DX11EffectTechnique * CEffect::GetTechniqueByIndex(UINT  Index)
2034 {
2035     LPCSTR pFuncName = "ID3DX11Effect::GetTechniqueByIndex";
2036
2037     if( Index < m_TechniqueCount )
2038     {
2039         UINT i;
2040         for( i=0; i < m_GroupCount; i++ )
2041         {
2042             if( Index < m_pGroups[i].TechniqueCount )
2043             {
2044                 return (ID3DX11EffectTechnique *)(m_pGroups[i].pTechniques + Index);
2045             }
2046             Index -= m_pGroups[i].TechniqueCount;
2047         }
2048         D3DXASSERT( FALSE );
2049     }
2050     DPF(0, "%s: Invalid technique index (%d)", pFuncName, Index);
2051     return &g_InvalidTechnique;
2052 }
2053
2054 ID3DX11EffectTechnique * CEffect::GetTechniqueByName(LPCSTR Name)
2055 {
2056     HRESULT hr = S_OK;
2057     LPCSTR pFuncName = "ID3DX11Effect::GetTechniqueByName";
2058     const UINT MAX_GROUP_TECHNIQUE_SIZE = 256;
2059     char NameCopy[MAX_GROUP_TECHNIQUE_SIZE];
2060
2061     if (IsOptimized())
2062     {
2063         DPF(0, "ID3DX11Effect::GetTechniqueByName: Cannot get technique interfaces by name since the effect has been Optimize()'ed");
2064         return &g_InvalidTechnique;
2065     }
2066
2067     if (NULL == Name)
2068     {
2069         DPF(0, "%s: Parameter Name was NULL.", pFuncName);
2070         return &g_InvalidTechnique;
2071     }
2072
2073     if( FAILED( StringCchCopyA( NameCopy, MAX_GROUP_TECHNIQUE_SIZE, Name ) ) )
2074     {
2075         DPF( 0, "Group|Technique name has a length greater than %d.", MAX_GROUP_TECHNIQUE_SIZE );
2076         return &g_InvalidTechnique;
2077     }
2078
2079     char* pDelimiter = strchr( NameCopy, '|' );
2080     if( pDelimiter == NULL )
2081     {
2082         if ( m_pNullGroup == NULL )
2083         {
2084             DPF( 0, "The effect contains no default group." );
2085             return &g_InvalidTechnique;
2086         }
2087
2088         return m_pNullGroup->GetTechniqueByName( Name );
2089     }
2090
2091     // separate group name and technique name
2092     *pDelimiter = 0; 
2093
2094     return GetGroupByName( NameCopy )->GetTechniqueByName( pDelimiter + 1 );
2095 }
2096
2097 ID3D11ClassLinkage * CEffect::GetClassLinkage()
2098 {
2099     SAFE_ADDREF( m_pClassLinkage );
2100     return m_pClassLinkage;
2101 }
2102
2103 ID3DX11EffectGroup * CEffect::GetGroupByIndex(UINT  Index)
2104 {
2105     LPCSTR pFuncName = "ID3DX11Effect::GetGroupByIndex";
2106
2107     if( Index < m_GroupCount )
2108     {
2109         return (ID3DX11EffectGroup *)(m_pGroups + Index);
2110     }
2111     DPF(0, "%s: Invalid group index (%d)", pFuncName, Index);
2112     return &g_InvalidGroup;
2113 }
2114
2115 ID3DX11EffectGroup * CEffect::GetGroupByName(LPCSTR Name)
2116 {
2117     HRESULT hr = S_OK;
2118     LPCSTR pFuncName = "ID3DX11Effect::GetGroupByName";
2119
2120     if (IsOptimized())
2121     {
2122         DPF(0, "ID3DX11Effect::GetGroupByName: Cannot get group interfaces by name since the effect has been Optimize()'ed");
2123         return &g_InvalidGroup;
2124     }
2125
2126     if (NULL == Name || Name[0] == 0 )
2127     {
2128         return m_pNullGroup ? (ID3DX11EffectGroup *)m_pNullGroup : &g_InvalidGroup;
2129     }
2130
2131     UINT  i;
2132
2133     for (i = 0; i < m_GroupCount; ++ i)
2134     {
2135         if (NULL != m_pGroups[i].pName && 
2136             strcmp(m_pGroups[i].pName, Name) == 0)
2137         {
2138             break;
2139         }
2140     }
2141
2142     if (i == m_GroupCount)
2143     {
2144         DPF(0, "%s: Group [%s] not found", pFuncName, Name);
2145         return &g_InvalidGroup;
2146     }
2147
2148     return (ID3DX11EffectGroup *)(m_pGroups + i);
2149 }
2150
2151 }