1266 lines
48 KiB
C++
1266 lines
48 KiB
C++
//--------------------------------------------------------------------------------------
|
|
// File: Effect.h
|
|
//
|
|
// Direct3D 11 Effects Header for ID3DX11Effect Implementation
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// http://go.microsoft.com/fwlink/p/?LinkId=271568
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#include "EffectBinaryFormat.h"
|
|
#include "IUnknownImp.h"
|
|
|
|
#ifdef _DEBUG
|
|
extern void __cdecl D3DXDebugPrintf(UINT lvl, _In_z_ _Printf_format_string_ LPCSTR szFormat, ...);
|
|
#define DPF D3DXDebugPrintf
|
|
#else
|
|
#define DPF
|
|
#endif
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4481)
|
|
// VS 2010 considers 'override' to be a extension, but it's part of C++11 as of VS 2012
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
using namespace D3DX11Core;
|
|
|
|
namespace D3DX11Effects
|
|
{
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Forward defines
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
struct SBaseBlock;
|
|
struct SShaderBlock;
|
|
struct SPassBlock;
|
|
struct SClassInstance;
|
|
struct SInterface;
|
|
struct SShaderResource;
|
|
struct SUnorderedAccessView;
|
|
struct SRenderTargetView;
|
|
struct SDepthStencilView;
|
|
struct SSamplerBlock;
|
|
struct SDepthStencilBlock;
|
|
struct SBlendBlock;
|
|
struct SRasterizerBlock;
|
|
struct SString;
|
|
struct SD3DShaderVTable;
|
|
struct SClassInstanceGlobalVariable;
|
|
|
|
struct SAssignment;
|
|
struct SVariable;
|
|
struct SGlobalVariable;
|
|
struct SAnnotation;
|
|
struct SConstantBuffer;
|
|
|
|
class CEffect;
|
|
class CEffectLoader;
|
|
|
|
enum ELhsType : int;
|
|
|
|
// Allows the use of 32-bit and 64-bit timers depending on platform type
|
|
typedef size_t Timer;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Reflection & Type structures
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// CEffectMatrix is used internally instead of float arrays
|
|
struct CEffectMatrix
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
float _11, _12, _13, _14;
|
|
float _21, _22, _23, _24;
|
|
float _31, _32, _33, _34;
|
|
float _41, _42, _43, _44;
|
|
|
|
};
|
|
float m[4][4];
|
|
};
|
|
};
|
|
|
|
struct CEffectVector4
|
|
{
|
|
float x;
|
|
float y;
|
|
float z;
|
|
float w;
|
|
};
|
|
|
|
union UDataPointer
|
|
{
|
|
void *pGeneric;
|
|
uint8_t *pNumeric;
|
|
float *pNumericFloat;
|
|
uint32_t *pNumericDword;
|
|
int *pNumericInt;
|
|
BOOL *pNumericBool;
|
|
SString *pString;
|
|
SShaderBlock *pShader;
|
|
SBaseBlock *pBlock;
|
|
SBlendBlock *pBlend;
|
|
SDepthStencilBlock *pDepthStencil;
|
|
SRasterizerBlock *pRasterizer;
|
|
SInterface *pInterface;
|
|
SShaderResource *pShaderResource;
|
|
SUnorderedAccessView *pUnorderedAccessView;
|
|
SRenderTargetView *pRenderTargetView;
|
|
SDepthStencilView *pDepthStencilView;
|
|
SSamplerBlock *pSampler;
|
|
CEffectVector4 *pVector;
|
|
CEffectMatrix *pMatrix;
|
|
UINT_PTR Offset;
|
|
};
|
|
|
|
enum EMemberDataType
|
|
{
|
|
MDT_ClassInstance,
|
|
MDT_BlendState,
|
|
MDT_DepthStencilState,
|
|
MDT_RasterizerState,
|
|
MDT_SamplerState,
|
|
MDT_Buffer,
|
|
MDT_ShaderResourceView,
|
|
};
|
|
|
|
struct SMemberDataPointer
|
|
{
|
|
EMemberDataType Type;
|
|
union
|
|
{
|
|
IUnknown *pGeneric;
|
|
ID3D11ClassInstance *pD3DClassInstance;
|
|
ID3D11BlendState *pD3DEffectsManagedBlendState;
|
|
ID3D11DepthStencilState *pD3DEffectsManagedDepthStencilState;
|
|
ID3D11RasterizerState *pD3DEffectsManagedRasterizerState;
|
|
ID3D11SamplerState *pD3DEffectsManagedSamplerState;
|
|
ID3D11Buffer *pD3DEffectsManagedConstantBuffer;
|
|
ID3D11ShaderResourceView*pD3DEffectsManagedTextureBuffer;
|
|
} Data;
|
|
};
|
|
|
|
struct SType : public ID3DX11EffectType
|
|
{
|
|
static const UINT_PTR c_InvalidIndex = (uint32_t) -1;
|
|
static const uint32_t c_ScalarSize = sizeof(uint32_t);
|
|
|
|
// packing rule constants
|
|
static const uint32_t c_ScalarsPerRegister = 4;
|
|
static const uint32_t c_RegisterSize = c_ScalarsPerRegister * c_ScalarSize; // must be a power of 2!!
|
|
|
|
EVarType VarType; // numeric, object, struct
|
|
uint32_t Elements; // # of array elements (0 for non-arrays)
|
|
char *pTypeName; // friendly name of the type: "VS_OUTPUT", "float4", etc.
|
|
|
|
// *Size and stride values are always 0 for object types
|
|
// *Annotations adhere to packing rules (even though they do not reside in constant buffers)
|
|
// for consistency's sake
|
|
//
|
|
// Packing rules:
|
|
// *Structures and array elements are always register aligned
|
|
// *Single-row values (or, for column major matrices, single-column) are greedily
|
|
// packed unless doing so would span a register boundary, in which case they are
|
|
// register aligned
|
|
|
|
uint32_t TotalSize; // Total size of this data type in a constant buffer from
|
|
// start to finish (padding in between elements is included,
|
|
// but padding at the end is not since that would require
|
|
// knowledge of the following data type).
|
|
|
|
uint32_t Stride; // Number of bytes to advance between elements.
|
|
// Typically a multiple of 16 for arrays, vectors, matrices.
|
|
// For scalars and small vectors/matrices, this can be 4 or 8.
|
|
|
|
uint32_t PackedSize; // Size, in bytes, of this data typed when fully packed
|
|
|
|
union
|
|
{
|
|
SBinaryNumericType NumericType;
|
|
EObjectType ObjectType; // not all values of EObjectType are valid here (e.g. constant buffer)
|
|
struct
|
|
{
|
|
SVariable *pMembers; // array of type instances describing structure members
|
|
uint32_t Members;
|
|
BOOL ImplementsInterface; // true if this type implements an interface
|
|
BOOL HasSuperClass; // true if this type has a parent class
|
|
} StructType;
|
|
void* InterfaceType; // nothing for interfaces
|
|
};
|
|
|
|
|
|
SType() :
|
|
VarType(EVT_Invalid),
|
|
Elements(0),
|
|
pTypeName(nullptr),
|
|
TotalSize(0),
|
|
Stride(0),
|
|
PackedSize(0)
|
|
{
|
|
C_ASSERT( sizeof(NumericType) <= sizeof(StructType) );
|
|
C_ASSERT( sizeof(ObjectType) <= sizeof(StructType) );
|
|
C_ASSERT( sizeof(InterfaceType) <= sizeof(StructType) );
|
|
ZeroMemory( &StructType, sizeof(StructType) );
|
|
}
|
|
|
|
bool IsEqual(SType *pOtherType) const;
|
|
|
|
bool IsObjectType(EObjectType ObjType) const
|
|
{
|
|
return IsObjectTypeHelper(VarType, ObjectType, ObjType);
|
|
}
|
|
bool IsShader() const
|
|
{
|
|
return IsShaderHelper(VarType, ObjectType);
|
|
}
|
|
bool BelongsInConstantBuffer() const
|
|
{
|
|
return (VarType == EVT_Numeric) || (VarType == EVT_Struct);
|
|
}
|
|
bool IsStateBlockObject() const
|
|
{
|
|
return IsStateBlockObjectHelper(VarType, ObjectType);
|
|
}
|
|
bool IsClassInstance() const
|
|
{
|
|
return (VarType == EVT_Struct) && StructType.ImplementsInterface;
|
|
}
|
|
bool IsInterface() const
|
|
{
|
|
return IsInterfaceHelper(VarType, ObjectType);
|
|
}
|
|
bool IsShaderResource() const
|
|
{
|
|
return IsShaderResourceHelper(VarType, ObjectType);
|
|
}
|
|
bool IsUnorderedAccessView() const
|
|
{
|
|
return IsUnorderedAccessViewHelper(VarType, ObjectType);
|
|
}
|
|
bool IsSampler() const
|
|
{
|
|
return IsSamplerHelper(VarType, ObjectType);
|
|
}
|
|
bool IsRenderTargetView() const
|
|
{
|
|
return IsRenderTargetViewHelper(VarType, ObjectType);
|
|
}
|
|
bool IsDepthStencilView() const
|
|
{
|
|
return IsDepthStencilViewHelper(VarType, ObjectType);
|
|
}
|
|
|
|
uint32_t GetTotalUnpackedSize(_In_ bool IsSingleElement) const;
|
|
uint32_t GetTotalPackedSize(_In_ bool IsSingleElement) const;
|
|
HRESULT GetDescHelper(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc, _In_ bool IsSingleElement) const;
|
|
|
|
STDMETHOD_(bool, IsValid)() override { return true; }
|
|
STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override { return GetDescHelper(pDesc, false); }
|
|
STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(_In_z_ LPCSTR Name) override;
|
|
STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(_In_z_ LPCSTR Semantic) override;
|
|
STDMETHOD_(LPCSTR, GetMemberName)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(LPCSTR, GetMemberSemantic)(_In_ uint32_t Index) override;
|
|
|
|
IUNKNOWN_IMP(SType, ID3DX11EffectType, IUnknown);
|
|
};
|
|
|
|
// Represents a type structure for a single element.
|
|
// It seems pretty trivial, but it has a different virtual table which enables
|
|
// us to accurately represent a type that consists of a single element
|
|
struct SSingleElementType : public ID3DX11EffectType
|
|
{
|
|
SType *pType;
|
|
|
|
STDMETHOD_(bool, IsValid)() override { return true; }
|
|
STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override { return ((SType*)pType)->GetDescHelper(pDesc, true); }
|
|
STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(uint32_t Index) override { return ((SType*)pType)->GetMemberTypeByIndex(Index); }
|
|
STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(LPCSTR Name) override { return ((SType*)pType)->GetMemberTypeByName(Name); }
|
|
STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(LPCSTR Semantic) override { return ((SType*)pType)->GetMemberTypeBySemantic(Semantic); }
|
|
STDMETHOD_(LPCSTR, GetMemberName)(uint32_t Index) override { return ((SType*)pType)->GetMemberName(Index); }
|
|
STDMETHOD_(LPCSTR, GetMemberSemantic)(uint32_t Index) override { return ((SType*)pType)->GetMemberSemantic(Index); }
|
|
|
|
IUNKNOWN_IMP(SSingleElementType, ID3DX11EffectType, IUnknown);
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Block definitions
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void * GetBlockByIndex(EVarType VarType, EObjectType ObjectType, void *pBaseBlock, uint32_t Index);
|
|
|
|
struct SBaseBlock
|
|
{
|
|
EBlockType BlockType;
|
|
|
|
bool IsUserManaged:1;
|
|
|
|
uint32_t AssignmentCount;
|
|
SAssignment *pAssignments;
|
|
|
|
SBaseBlock();
|
|
|
|
bool ApplyAssignments(CEffect *pEffect);
|
|
|
|
inline SSamplerBlock *AsSampler() const
|
|
{
|
|
assert( BlockType == EBT_Sampler );
|
|
return (SSamplerBlock*) this;
|
|
}
|
|
|
|
inline SDepthStencilBlock *AsDepthStencil() const
|
|
{
|
|
assert( BlockType == EBT_DepthStencil );
|
|
return (SDepthStencilBlock*) this;
|
|
}
|
|
|
|
inline SBlendBlock *AsBlend() const
|
|
{
|
|
assert( BlockType == EBT_Blend );
|
|
return (SBlendBlock*) this;
|
|
}
|
|
|
|
inline SRasterizerBlock *AsRasterizer() const
|
|
{
|
|
assert( BlockType == EBT_Rasterizer );
|
|
return (SRasterizerBlock*) this;
|
|
}
|
|
|
|
inline SPassBlock *AsPass() const
|
|
{
|
|
assert( BlockType == EBT_Pass );
|
|
return (SPassBlock*) this;
|
|
}
|
|
};
|
|
|
|
struct STechnique : public ID3DX11EffectTechnique
|
|
{
|
|
char *pName;
|
|
|
|
uint32_t PassCount;
|
|
SPassBlock *pPasses;
|
|
|
|
uint32_t AnnotationCount;
|
|
SAnnotation *pAnnotations;
|
|
|
|
bool InitiallyValid;
|
|
bool HasDependencies;
|
|
|
|
STechnique();
|
|
|
|
STDMETHOD_(bool, IsValid)() override;
|
|
STDMETHOD(GetDesc)(_Out_ D3DX11_TECHNIQUE_DESC *pDesc) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectPass*, GetPassByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectPass*, GetPassByName)(_In_z_ LPCSTR Name) override;
|
|
|
|
STDMETHOD(ComputeStateBlockMask)(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask) override;
|
|
|
|
IUNKNOWN_IMP(STechnique, ID3DX11EffectTechnique, IUnknown);
|
|
};
|
|
|
|
struct SGroup : public ID3DX11EffectGroup
|
|
{
|
|
char *pName;
|
|
|
|
uint32_t TechniqueCount;
|
|
STechnique *pTechniques;
|
|
|
|
uint32_t AnnotationCount;
|
|
SAnnotation *pAnnotations;
|
|
|
|
bool InitiallyValid;
|
|
bool HasDependencies;
|
|
|
|
SGroup();
|
|
|
|
STDMETHOD_(bool, IsValid)() override;
|
|
STDMETHOD(GetDesc)(_Out_ D3DX11_GROUP_DESC *pDesc) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByName)(_In_z_ LPCSTR Name) override;
|
|
|
|
IUNKNOWN_IMP(SGroup, ID3DX11EffectGroup, IUnknown);
|
|
};
|
|
|
|
struct SPassBlock : SBaseBlock, public ID3DX11EffectPass
|
|
{
|
|
struct
|
|
{
|
|
ID3D11BlendState* pBlendState;
|
|
FLOAT BlendFactor[4];
|
|
uint32_t SampleMask;
|
|
ID3D11DepthStencilState *pDepthStencilState;
|
|
uint32_t StencilRef;
|
|
union
|
|
{
|
|
D3D11_SO_DECLARATION_ENTRY *pEntry;
|
|
char *pEntryDesc;
|
|
} GSSODesc;
|
|
|
|
// Pass assignments can write directly into these
|
|
SBlendBlock *pBlendBlock;
|
|
SDepthStencilBlock *pDepthStencilBlock;
|
|
SRasterizerBlock *pRasterizerBlock;
|
|
uint32_t RenderTargetViewCount;
|
|
SRenderTargetView *pRenderTargetViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
|
|
SDepthStencilView *pDepthStencilView;
|
|
SShaderBlock *pVertexShaderBlock;
|
|
SShaderBlock *pPixelShaderBlock;
|
|
SShaderBlock *pGeometryShaderBlock;
|
|
SShaderBlock *pComputeShaderBlock;
|
|
SShaderBlock *pDomainShaderBlock;
|
|
SShaderBlock *pHullShaderBlock;
|
|
} BackingStore;
|
|
|
|
char *pName;
|
|
|
|
uint32_t AnnotationCount;
|
|
SAnnotation *pAnnotations;
|
|
|
|
CEffect *pEffect;
|
|
|
|
bool InitiallyValid; // validity of all state objects and shaders in pass upon BindToDevice
|
|
bool HasDependencies; // if pass expressions or pass state blocks have dependencies on variables (if true, IsValid != InitiallyValid possibly)
|
|
|
|
SPassBlock();
|
|
|
|
void ApplyPassAssignments();
|
|
bool CheckShaderDependencies( _In_ const SShaderBlock* pBlock );
|
|
bool CheckDependencies();
|
|
|
|
template<EObjectType EShaderType>
|
|
HRESULT GetShaderDescHelper(_Out_ D3DX11_PASS_SHADER_DESC *pDesc);
|
|
|
|
STDMETHOD_(bool, IsValid)() override;
|
|
STDMETHOD(GetDesc)(_Out_ D3DX11_PASS_DESC *pDesc) override;
|
|
|
|
STDMETHOD(GetVertexShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
|
|
STDMETHOD(GetGeometryShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
|
|
STDMETHOD(GetPixelShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
|
|
STDMETHOD(GetHullShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
|
|
STDMETHOD(GetDomainShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
|
|
STDMETHOD(GetComputeShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
|
|
|
|
STDMETHOD(Apply)(_In_ uint32_t Flags, _In_ ID3D11DeviceContext* pContext) override;
|
|
|
|
STDMETHOD(ComputeStateBlockMask)(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask) override;
|
|
|
|
IUNKNOWN_IMP(SPassBlock, ID3DX11EffectPass, IUnknown);
|
|
};
|
|
|
|
struct SDepthStencilBlock : SBaseBlock
|
|
{
|
|
ID3D11DepthStencilState *pDSObject;
|
|
D3D11_DEPTH_STENCIL_DESC BackingStore;
|
|
bool IsValid;
|
|
|
|
SDepthStencilBlock();
|
|
};
|
|
|
|
struct SBlendBlock : SBaseBlock
|
|
{
|
|
ID3D11BlendState *pBlendObject;
|
|
D3D11_BLEND_DESC BackingStore;
|
|
bool IsValid;
|
|
|
|
SBlendBlock();
|
|
};
|
|
|
|
struct SRasterizerBlock : SBaseBlock
|
|
{
|
|
ID3D11RasterizerState *pRasterizerObject;
|
|
D3D11_RASTERIZER_DESC BackingStore;
|
|
bool IsValid;
|
|
|
|
SRasterizerBlock();
|
|
};
|
|
|
|
struct SSamplerBlock : SBaseBlock
|
|
{
|
|
ID3D11SamplerState *pD3DObject;
|
|
struct
|
|
{
|
|
D3D11_SAMPLER_DESC SamplerDesc;
|
|
// Sampler "TEXTURE" assignments can write directly into this
|
|
SShaderResource *pTexture;
|
|
} BackingStore;
|
|
|
|
SSamplerBlock();
|
|
};
|
|
|
|
struct SInterface
|
|
{
|
|
SClassInstanceGlobalVariable* pClassInstance;
|
|
|
|
SInterface()
|
|
{
|
|
pClassInstance = nullptr;
|
|
}
|
|
};
|
|
|
|
struct SShaderResource
|
|
{
|
|
ID3D11ShaderResourceView *pShaderResource;
|
|
|
|
SShaderResource()
|
|
{
|
|
pShaderResource = nullptr;
|
|
}
|
|
|
|
};
|
|
|
|
struct SUnorderedAccessView
|
|
{
|
|
ID3D11UnorderedAccessView *pUnorderedAccessView;
|
|
|
|
SUnorderedAccessView()
|
|
{
|
|
pUnorderedAccessView = nullptr;
|
|
}
|
|
|
|
};
|
|
|
|
struct SRenderTargetView
|
|
{
|
|
ID3D11RenderTargetView *pRenderTargetView;
|
|
|
|
SRenderTargetView();
|
|
};
|
|
|
|
struct SDepthStencilView
|
|
{
|
|
ID3D11DepthStencilView *pDepthStencilView;
|
|
|
|
SDepthStencilView();
|
|
};
|
|
|
|
|
|
template<class T, class D3DTYPE> struct SShaderDependency
|
|
{
|
|
uint32_t StartIndex;
|
|
uint32_t Count;
|
|
|
|
T *ppFXPointers; // Array of ptrs to FX objects (CBs, SShaderResources, etc)
|
|
D3DTYPE *ppD3DObjects; // Array of ptrs to matching D3D objects
|
|
|
|
SShaderDependency()
|
|
{
|
|
StartIndex = Count = 0;
|
|
|
|
ppD3DObjects = nullptr;
|
|
ppFXPointers = nullptr;
|
|
}
|
|
};
|
|
|
|
typedef SShaderDependency<SConstantBuffer*, ID3D11Buffer*> SShaderCBDependency;
|
|
typedef SShaderDependency<SSamplerBlock*, ID3D11SamplerState*> SShaderSamplerDependency;
|
|
typedef SShaderDependency<SShaderResource*, ID3D11ShaderResourceView*> SShaderResourceDependency;
|
|
typedef SShaderDependency<SUnorderedAccessView*, ID3D11UnorderedAccessView*> SUnorderedAccessViewDependency;
|
|
typedef SShaderDependency<SInterface*, ID3D11ClassInstance*> SInterfaceDependency;
|
|
|
|
// Shader VTables are used to eliminate branching in ApplyShaderBlock.
|
|
// The effect owns one D3DShaderVTables for each shader stage
|
|
struct SD3DShaderVTable
|
|
{
|
|
void ( __stdcall ID3D11DeviceContext::*pSetShader)(ID3D11DeviceChild* pShader, ID3D11ClassInstance*const* ppClassInstances, uint32_t NumClassInstances);
|
|
void ( __stdcall ID3D11DeviceContext::*pSetConstantBuffers)(uint32_t StartConstantSlot, uint32_t NumBuffers, ID3D11Buffer *const *pBuffers);
|
|
void ( __stdcall ID3D11DeviceContext::*pSetSamplers)(uint32_t Offset, uint32_t NumSamplers, ID3D11SamplerState*const* pSamplers);
|
|
void ( __stdcall ID3D11DeviceContext::*pSetShaderResources)(uint32_t Offset, uint32_t NumResources, ID3D11ShaderResourceView *const *pResources);
|
|
HRESULT ( __stdcall ID3D11Device::*pCreateShader)(const void *pShaderBlob, size_t ShaderBlobSize, ID3D11ClassLinkage* pClassLinkage, ID3D11DeviceChild **ppShader);
|
|
};
|
|
|
|
|
|
struct SShaderBlock
|
|
{
|
|
enum ESigType
|
|
{
|
|
ST_Input,
|
|
ST_Output,
|
|
ST_PatchConstant,
|
|
};
|
|
|
|
struct SInterfaceParameter
|
|
{
|
|
char *pName;
|
|
uint32_t Index;
|
|
};
|
|
|
|
// this data is classified as reflection-only and will all be discarded at runtime
|
|
struct SReflectionData
|
|
{
|
|
uint8_t *pBytecode;
|
|
uint32_t BytecodeLength;
|
|
char *pStreamOutDecls[4]; // set with ConstructGSWithSO
|
|
uint32_t RasterizedStream; // set with ConstructGSWithSO
|
|
BOOL IsNullGS;
|
|
ID3D11ShaderReflection *pReflection;
|
|
uint32_t InterfaceParameterCount; // set with BindInterfaces (used for function interface parameters)
|
|
SInterfaceParameter *pInterfaceParameters; // set with BindInterfaces (used for function interface parameters)
|
|
};
|
|
|
|
bool IsValid;
|
|
SD3DShaderVTable *pVT;
|
|
|
|
// This value is nullptr if the shader is nullptr or was never initialized
|
|
SReflectionData *pReflectionData;
|
|
|
|
ID3D11DeviceChild *pD3DObject;
|
|
|
|
uint32_t CBDepCount;
|
|
SShaderCBDependency *pCBDeps;
|
|
|
|
uint32_t SampDepCount;
|
|
SShaderSamplerDependency *pSampDeps;
|
|
|
|
uint32_t InterfaceDepCount;
|
|
SInterfaceDependency *pInterfaceDeps;
|
|
|
|
uint32_t ResourceDepCount;
|
|
SShaderResourceDependency *pResourceDeps;
|
|
|
|
uint32_t UAVDepCount;
|
|
SUnorderedAccessViewDependency *pUAVDeps;
|
|
|
|
uint32_t TBufferDepCount;
|
|
SConstantBuffer **ppTbufDeps;
|
|
|
|
ID3DBlob *pInputSignatureBlob; // The input signature is separated from the bytecode because it
|
|
// is always available, even after Optimize() has been called.
|
|
|
|
SShaderBlock(SD3DShaderVTable *pVirtualTable = nullptr);
|
|
|
|
EObjectType GetShaderType();
|
|
|
|
HRESULT OnDeviceBind();
|
|
|
|
// Public API helpers
|
|
HRESULT ComputeStateBlockMask(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask);
|
|
|
|
HRESULT GetShaderDesc(_Out_ D3DX11_EFFECT_SHADER_DESC *pDesc, _In_ bool IsInline);
|
|
|
|
HRESULT GetVertexShader(_Outptr_ ID3D11VertexShader **ppVS);
|
|
HRESULT GetGeometryShader(_Outptr_ ID3D11GeometryShader **ppGS);
|
|
HRESULT GetPixelShader(_Outptr_ ID3D11PixelShader **ppPS);
|
|
HRESULT GetHullShader(_Outptr_ ID3D11HullShader **ppHS);
|
|
HRESULT GetDomainShader(_Outptr_ ID3D11DomainShader **ppDS);
|
|
HRESULT GetComputeShader(_Outptr_ ID3D11ComputeShader **ppCS);
|
|
|
|
HRESULT GetSignatureElementDesc(_In_ ESigType SigType, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc);
|
|
};
|
|
|
|
|
|
|
|
struct SString
|
|
{
|
|
char *pString;
|
|
|
|
SString();
|
|
};
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Global Variable & Annotation structure/interface definitions
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// This is a general structure that can describe
|
|
// annotations, variables, and structure members
|
|
//
|
|
struct SVariable
|
|
{
|
|
// For annotations/variables/variable members:
|
|
// 1) If numeric, pointer to data (for variables: points into backing store,
|
|
// for annotations, points into reflection heap)
|
|
// OR
|
|
// 2) If object, pointer to the block. If object array, subsequent array elements are found in
|
|
// contiguous blocks; the Nth block is found by ((<SpecificBlockType> *) pBlock) + N
|
|
// (this is because variables that are arrays of objects have their blocks allocated contiguously)
|
|
//
|
|
// For structure members:
|
|
// Offset of this member (in bytes) from parent structure (structure members must be numeric/struct)
|
|
UDataPointer Data;
|
|
union
|
|
{
|
|
uint32_t MemberDataOffsetPlus4; // 4 added so that 0 == nullptr can represent "unused"
|
|
SMemberDataPointer *pMemberData;
|
|
};
|
|
|
|
SType *pType;
|
|
char *pName;
|
|
char *pSemantic;
|
|
uint32_t ExplicitBindPoint;
|
|
|
|
SVariable()
|
|
{
|
|
ZeroMemory(this, sizeof(*this));
|
|
ExplicitBindPoint = uint32_t(-1);
|
|
}
|
|
};
|
|
|
|
// Template definitions for all of the various ID3DX11EffectVariable specializations
|
|
#include "EffectVariable.inl"
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// ID3DX11EffectShaderVariable (SAnonymousShader implementation)
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
struct SAnonymousShader : public TUncastableVariable<ID3DX11EffectShaderVariable>, public ID3DX11EffectType
|
|
{
|
|
SShaderBlock *pShaderBlock;
|
|
|
|
SAnonymousShader(_In_opt_ SShaderBlock *pBlock = nullptr);
|
|
|
|
// ID3DX11EffectShaderVariable interface
|
|
STDMETHOD_(bool, IsValid)() override;
|
|
STDMETHOD_(ID3DX11EffectType*, GetType)() override;
|
|
STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetMemberByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetMemberByName)(_In_z_ LPCSTR Name) override;
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetMemberBySemantic)(_In_z_ LPCSTR Semantic) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetElement)(_In_ uint32_t Index) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)() override;
|
|
|
|
// other casts are handled by TUncastableVariable
|
|
STDMETHOD_(ID3DX11EffectShaderVariable*, AsShader)() override;
|
|
|
|
STDMETHOD(SetRawValue)(_In_reads_bytes_(Count) const void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
|
|
STDMETHOD(GetRawValue)(_Out_writes_bytes_(Count) void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
|
|
|
|
STDMETHOD(GetShaderDesc)(_In_ uint32_t ShaderIndex, _Out_ D3DX11_EFFECT_SHADER_DESC *pDesc) override;
|
|
|
|
STDMETHOD(GetVertexShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11VertexShader **ppVS) override;
|
|
STDMETHOD(GetGeometryShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11GeometryShader **ppGS) override;
|
|
STDMETHOD(GetPixelShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11PixelShader **ppPS) override;
|
|
STDMETHOD(GetHullShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11HullShader **ppHS) override;
|
|
STDMETHOD(GetDomainShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11DomainShader **ppDS) override;
|
|
STDMETHOD(GetComputeShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11ComputeShader **ppCS) override;
|
|
|
|
STDMETHOD(GetInputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override;
|
|
STDMETHOD(GetOutputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override;
|
|
STDMETHOD(GetPatchConstantSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override;
|
|
|
|
// ID3DX11EffectType interface
|
|
STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override;
|
|
STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(_In_z_ LPCSTR Name) override;
|
|
STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(_In_z_ LPCSTR Semantic) override;
|
|
|
|
STDMETHOD_(LPCSTR, GetMemberName)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(LPCSTR, GetMemberSemantic)(_In_ uint32_t Index) override;
|
|
|
|
IUNKNOWN_IMP(SAnonymousShader, ID3DX11EffectShaderVariable, ID3DX11EffectVariable);
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// ID3DX11EffectConstantBuffer (SConstantBuffer implementation)
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
struct SConstantBuffer : public TUncastableVariable<ID3DX11EffectConstantBuffer>, public ID3DX11EffectType
|
|
{
|
|
ID3D11Buffer *pD3DObject;
|
|
SShaderResource TBuffer; // nullptr iff IsTbuffer == false
|
|
|
|
uint8_t *pBackingStore;
|
|
uint32_t Size; // in bytes
|
|
|
|
char *pName;
|
|
|
|
uint32_t AnnotationCount;
|
|
SAnnotation *pAnnotations;
|
|
|
|
uint32_t VariableCount; // # of variables contained in this cbuffer
|
|
SGlobalVariable *pVariables; // array of size [VariableCount], points into effect's contiguous variable list
|
|
uint32_t ExplicitBindPoint; // Used when a CB has been explicitly bound (register(bXX)). -1 if not
|
|
|
|
bool IsDirty:1; // Set when any member is updated; cleared on CB apply
|
|
bool IsTBuffer:1; // true iff TBuffer.pShaderResource != nullptr
|
|
bool IsUserManaged:1; // Set if you don't want effects to update this buffer
|
|
bool IsEffectOptimized:1;// Set if the effect has been optimized
|
|
bool IsUsedByExpression:1;// Set if used by any expressions
|
|
bool IsUserPacked:1; // Set if the elements have user-specified offsets
|
|
bool IsSingle:1; // Set to true if you want to share this CB with cloned Effects
|
|
bool IsNonUpdatable:1; // Set to true if you want to share this CB with cloned Effects
|
|
|
|
union
|
|
{
|
|
// These are used to store the original ID3D11Buffer* for use in UndoSetConstantBuffer
|
|
uint32_t MemberDataOffsetPlus4; // 4 added so that 0 == nullptr can represent "unused"
|
|
SMemberDataPointer *pMemberData;
|
|
};
|
|
|
|
CEffect *pEffect;
|
|
|
|
SConstantBuffer()
|
|
{
|
|
pD3DObject = nullptr;
|
|
ZeroMemory(&TBuffer, sizeof(TBuffer));
|
|
ExplicitBindPoint = uint32_t(-1);
|
|
pBackingStore = nullptr;
|
|
Size = 0;
|
|
pName = nullptr;
|
|
VariableCount = 0;
|
|
pVariables = nullptr;
|
|
AnnotationCount = 0;
|
|
pAnnotations = nullptr;
|
|
IsDirty = false;
|
|
IsTBuffer = false;
|
|
IsUserManaged = false;
|
|
IsEffectOptimized = false;
|
|
IsUsedByExpression = false;
|
|
IsUserPacked = false;
|
|
IsSingle = false;
|
|
IsNonUpdatable = false;
|
|
pEffect = nullptr;
|
|
}
|
|
|
|
bool ClonedSingle() const;
|
|
|
|
// ID3DX11EffectConstantBuffer interface
|
|
STDMETHOD_(bool, IsValid)() override;
|
|
STDMETHOD_(ID3DX11EffectType*, GetType)() override;
|
|
STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetMemberByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetMemberByName)(_In_z_ LPCSTR Name) override;
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetMemberBySemantic)(_In_z_ LPCSTR Semantic) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetElement)(_In_ uint32_t Index) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)() override;
|
|
|
|
// other casts are handled by TUncastableVariable
|
|
STDMETHOD_(ID3DX11EffectConstantBuffer*, AsConstantBuffer)() override;
|
|
|
|
STDMETHOD(SetRawValue)(_In_reads_bytes_(Count) const void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
|
|
STDMETHOD(GetRawValue)(_Out_writes_bytes_(Count) void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
|
|
|
|
STDMETHOD(SetConstantBuffer)(_In_ ID3D11Buffer *pConstantBuffer) override;
|
|
STDMETHOD(GetConstantBuffer)(_Outptr_ ID3D11Buffer **ppConstantBuffer) override;
|
|
STDMETHOD(UndoSetConstantBuffer)() override;
|
|
|
|
STDMETHOD(SetTextureBuffer)(_In_ ID3D11ShaderResourceView *pTextureBuffer) override;
|
|
STDMETHOD(GetTextureBuffer)(_Outptr_ ID3D11ShaderResourceView **ppTextureBuffer) override;
|
|
STDMETHOD(UndoSetTextureBuffer)() override;
|
|
|
|
// ID3DX11EffectType interface
|
|
STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override;
|
|
STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(_In_z_ LPCSTR Name) override;
|
|
STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(_In_z_ LPCSTR Semantic) override;
|
|
|
|
STDMETHOD_(LPCSTR, GetMemberName)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(LPCSTR, GetMemberSemantic)(_In_ uint32_t Index) override;
|
|
|
|
IUNKNOWN_IMP(SConstantBuffer, ID3DX11EffectConstantBuffer, ID3DX11EffectVariable);
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Assignments
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
enum ERuntimeAssignmentType
|
|
{
|
|
ERAT_Invalid,
|
|
// [Destination] refers to the destination location, which is always the backing store of the pass/state block.
|
|
// [Source] refers to the current source of data, always coming from either a constant buffer's
|
|
// backing store (for numeric assignments), an object variable's block array, or an anonymous (unowned) block
|
|
|
|
// Numeric variables:
|
|
ERAT_Constant, // Source is unused.
|
|
// No dependencies; this assignment can be safely removed after load.
|
|
ERAT_NumericVariable, // Source points to the CB's backing store where the value lives.
|
|
// 1 dependency: the variable itself.
|
|
ERAT_NumericConstIndex, // Source points to the CB's backing store where the value lives, offset by N.
|
|
// 1 dependency: the variable array being indexed.
|
|
ERAT_NumericVariableIndex, // Source points to the last used element of the variable in the CB's backing store.
|
|
// 2 dependencies: the index variable followed by the array variable.
|
|
|
|
// Object variables:
|
|
ERAT_ObjectInlineShader, // An anonymous, immutable shader block pointer is copied to the destination immediately.
|
|
// No dependencies; this assignment can be safely removed after load.
|
|
ERAT_ObjectVariable, // A pointer to the block owned by the object variable is copied to the destination immediately.
|
|
// No dependencies; this assignment can be safely removed after load.
|
|
ERAT_ObjectConstIndex, // A pointer to the Nth block owned by an object variable is copied to the destination immediately.
|
|
// No dependencies; this assignment can be safely removed after load.
|
|
ERAT_ObjectVariableIndex, // Source points to the first block owned by an object variable array
|
|
// (the offset from this, N, is taken from another variable).
|
|
// 1 dependency: the variable being used to index the array.
|
|
};
|
|
|
|
struct SAssignment
|
|
{
|
|
struct SDependency
|
|
{
|
|
SGlobalVariable *pVariable;
|
|
|
|
SDependency()
|
|
{
|
|
pVariable = nullptr;
|
|
}
|
|
};
|
|
|
|
ELhsType LhsType; // PS, VS, DepthStencil etc.
|
|
|
|
// The value of SAssignment.AssignmentType determines how the other fields behave
|
|
// (DependencyCount, pDependencies, Destination, and Source)
|
|
ERuntimeAssignmentType AssignmentType;
|
|
|
|
Timer LastRecomputedTime;
|
|
|
|
// see comments in ERuntimeAssignmentType for how dependencies and data pointers are handled
|
|
uint32_t DependencyCount;
|
|
SDependency *pDependencies;
|
|
|
|
UDataPointer Destination; // This value never changes after load, and always refers to the backing store
|
|
UDataPointer Source; // This value, on the other hand, can change if variable- or expression- driven
|
|
|
|
uint32_t DataSize : 16; // Size of the data element to be copied in bytes (if numeric) or
|
|
// stride of the block type (if object)
|
|
uint32_t MaxElements : 16; // Max allowable index (needed because we don't store object arrays as dependencies,
|
|
// and therefore have no way of getting their Element count)
|
|
|
|
bool IsObjectAssignment() // True for Shader and RObject assignments (the type that appear in pass blocks)
|
|
{
|
|
return IsObjectAssignmentHelper(LhsType);
|
|
}
|
|
|
|
SAssignment()
|
|
{
|
|
LhsType = ELHS_Invalid;
|
|
AssignmentType = ERAT_Invalid;
|
|
|
|
Destination.pGeneric = nullptr;
|
|
Source.pGeneric = nullptr;
|
|
|
|
LastRecomputedTime = 0;
|
|
DependencyCount = 0;
|
|
pDependencies = nullptr;
|
|
|
|
DataSize = 0;
|
|
}
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Private effect heaps
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Used to efficiently reallocate data
|
|
// 1) For every piece of data that needs reallocation, move it to its new location
|
|
// and add an entry into the table
|
|
// 2) For everyone that references one of these data blocks, do a quick table lookup
|
|
// to find the old pointer and then replace it with the new one
|
|
struct SPointerMapping
|
|
{
|
|
void *pOld;
|
|
void *pNew;
|
|
|
|
static bool AreMappingsEqual(const SPointerMapping &pMap1, const SPointerMapping &pMap2)
|
|
{
|
|
return (pMap1.pOld == pMap2.pOld);
|
|
}
|
|
|
|
uint32_t Hash()
|
|
{
|
|
// hash the pointer itself
|
|
// (using the pointer as a hash would be very bad)
|
|
return ComputeHash((uint8_t*)&pOld, sizeof(pOld));
|
|
}
|
|
};
|
|
|
|
typedef CEffectHashTableWithPrivateHeap<SPointerMapping, SPointerMapping::AreMappingsEqual> CPointerMappingTable;
|
|
|
|
// Assist adding data to a block of memory
|
|
class CEffectHeap
|
|
{
|
|
protected:
|
|
uint8_t *m_pData;
|
|
uint32_t m_dwBufferSize;
|
|
uint32_t m_dwSize;
|
|
|
|
template <bool bCopyData>
|
|
HRESULT AddDataInternal(_In_reads_bytes_(dwSize) const void *pData, _In_ uint32_t dwSize, _Outptr_ void **ppPointer);
|
|
|
|
public:
|
|
HRESULT ReserveMemory(uint32_t dwSize);
|
|
uint32_t GetSize();
|
|
uint8_t* GetDataStart() { return m_pData; }
|
|
|
|
// AddData and AddString append existing data to the buffer - they change m_dwSize. Users are
|
|
// not expected to modify the data pointed to by the return pointer
|
|
HRESULT AddString(_In_z_ const char *pString, _Outptr_result_z_ char **ppPointer);
|
|
HRESULT AddData(_In_reads_(dwSize) const void *pData, _In_ uint32_t dwSize, _Outptr_ void **ppPointer);
|
|
|
|
// Allocate behaves like a standard new - it will allocate memory, move m_dwSize. The caller is
|
|
// expected to use the returned pointer
|
|
void* Allocate(uint32_t dwSize);
|
|
|
|
// Move data from the general heap and optional free memory
|
|
HRESULT MoveData(_Inout_updates_bytes_(size) void **ppData, _In_ uint32_t size);
|
|
HRESULT MoveString(_Inout_updates_z_(1) char **ppStringData);
|
|
HRESULT MoveInterfaceParameters(_In_ uint32_t InterfaceCount, _Inout_updates_(1) SShaderBlock::SInterfaceParameter **ppInterfaces);
|
|
HRESULT MoveEmptyDataBlock(_Inout_updates_(1) void **ppData, _In_ uint32_t size);
|
|
|
|
bool IsInHeap(_In_ void *pData) const
|
|
{
|
|
return (pData >= m_pData && pData < (m_pData + m_dwBufferSize));
|
|
}
|
|
|
|
CEffectHeap();
|
|
~CEffectHeap();
|
|
};
|
|
|
|
class CEffectReflection
|
|
{
|
|
public:
|
|
// Single memory block support
|
|
CEffectHeap m_Heap;
|
|
};
|
|
|
|
|
|
class CEffect : public ID3DX11Effect
|
|
{
|
|
friend struct SBaseBlock;
|
|
friend struct SPassBlock;
|
|
friend class CEffectLoader;
|
|
friend struct SConstantBuffer;
|
|
friend struct TSamplerVariable<TGlobalVariable<ID3DX11EffectSamplerVariable>>;
|
|
friend struct TSamplerVariable<TVariable<TMember<ID3DX11EffectSamplerVariable>>>;
|
|
|
|
protected:
|
|
|
|
uint32_t m_RefCount;
|
|
uint32_t m_Flags;
|
|
|
|
// Private heap - all pointers should point into here
|
|
CEffectHeap m_Heap;
|
|
|
|
// Reflection object
|
|
CEffectReflection *m_pReflection;
|
|
|
|
// global variables in the effect (aka parameters)
|
|
uint32_t m_VariableCount;
|
|
SGlobalVariable *m_pVariables;
|
|
|
|
// anonymous shader variables (one for every inline shader assignment)
|
|
uint32_t m_AnonymousShaderCount;
|
|
SAnonymousShader *m_pAnonymousShaders;
|
|
|
|
// techniques within this effect (the actual data is located in each group)
|
|
uint32_t m_TechniqueCount;
|
|
|
|
// groups within this effect
|
|
uint32_t m_GroupCount;
|
|
SGroup *m_pGroups;
|
|
SGroup *m_pNullGroup;
|
|
|
|
uint32_t m_ShaderBlockCount;
|
|
SShaderBlock *m_pShaderBlocks;
|
|
|
|
uint32_t m_DepthStencilBlockCount;
|
|
SDepthStencilBlock *m_pDepthStencilBlocks;
|
|
|
|
uint32_t m_BlendBlockCount;
|
|
SBlendBlock *m_pBlendBlocks;
|
|
|
|
uint32_t m_RasterizerBlockCount;
|
|
SRasterizerBlock *m_pRasterizerBlocks;
|
|
|
|
uint32_t m_SamplerBlockCount;
|
|
SSamplerBlock *m_pSamplerBlocks;
|
|
|
|
uint32_t m_MemberDataCount;
|
|
SMemberDataPointer *m_pMemberDataBlocks;
|
|
|
|
uint32_t m_InterfaceCount;
|
|
SInterface *m_pInterfaces;
|
|
|
|
uint32_t m_CBCount;
|
|
SConstantBuffer *m_pCBs;
|
|
|
|
uint32_t m_StringCount;
|
|
SString *m_pStrings;
|
|
|
|
uint32_t m_ShaderResourceCount;
|
|
SShaderResource *m_pShaderResources;
|
|
|
|
uint32_t m_UnorderedAccessViewCount;
|
|
SUnorderedAccessView *m_pUnorderedAccessViews;
|
|
|
|
uint32_t m_RenderTargetViewCount;
|
|
SRenderTargetView *m_pRenderTargetViews;
|
|
|
|
uint32_t m_DepthStencilViewCount;
|
|
SDepthStencilView *m_pDepthStencilViews;
|
|
|
|
Timer m_LocalTimer;
|
|
|
|
// temporary index variable for assignment evaluation
|
|
uint32_t m_FXLIndex;
|
|
|
|
ID3D11Device *m_pDevice;
|
|
ID3D11DeviceContext *m_pContext;
|
|
ID3D11ClassLinkage *m_pClassLinkage;
|
|
|
|
// Master lists of reflection interfaces
|
|
CEffectVectorOwner<SSingleElementType> m_pTypeInterfaces;
|
|
CEffectVectorOwner<SMember> m_pMemberInterfaces;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// String & Type pooling
|
|
|
|
typedef SType *LPSRUNTIMETYPE;
|
|
static bool AreTypesEqual(const LPSRUNTIMETYPE &pType1, const LPSRUNTIMETYPE &pType2) { return (pType1->IsEqual(pType2)); }
|
|
static bool AreStringsEqual(const LPCSTR &pStr1, const LPCSTR &pStr2) { return strcmp(pStr1, pStr2) == 0; }
|
|
|
|
typedef CEffectHashTableWithPrivateHeap<SType *, AreTypesEqual> CTypeHashTable;
|
|
typedef CEffectHashTableWithPrivateHeap<LPCSTR, AreStringsEqual> CStringHashTable;
|
|
|
|
// These are used to pool types & type-related strings
|
|
// until Optimize() is called
|
|
CTypeHashTable *m_pTypePool;
|
|
CStringHashTable *m_pStringPool;
|
|
CDataBlockStore *m_pPooledHeap;
|
|
// After Optimize() is called, the type/string pools should be deleted and all
|
|
// remaining data should be migrated into the optimized type heap
|
|
CEffectHeap *m_pOptimizedTypeHeap;
|
|
|
|
// Pools a string or type and modifies the pointer
|
|
void AddStringToPool(const char **ppString);
|
|
void AddTypeToPool(SType **ppType);
|
|
|
|
HRESULT OptimizeTypes(_Inout_ CPointerMappingTable *pMappingTable, _In_ bool Cloning = false);
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Runtime (performance critical)
|
|
|
|
void ApplyShaderBlock(_In_ SShaderBlock *pBlock);
|
|
bool ApplyRenderStateBlock(_In_ SBaseBlock *pBlock);
|
|
bool ApplySamplerBlock(_In_ SSamplerBlock *pBlock);
|
|
void ApplyPassBlock(_Inout_ SPassBlock *pBlock);
|
|
bool EvaluateAssignment(_Inout_ SAssignment *pAssignment);
|
|
bool ValidateShaderBlock(_Inout_ SShaderBlock* pBlock );
|
|
bool ValidatePassBlock(_Inout_ SPassBlock* pBlock );
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Non-runtime functions (not performance critical)
|
|
|
|
SGlobalVariable *FindLocalVariableByName(_In_z_ LPCSTR pVarName); // Looks in the current effect only
|
|
SGlobalVariable *FindVariableByName(_In_z_ LPCSTR pVarName);
|
|
SVariable *FindVariableByNameWithParsing(_In_z_ LPCSTR pVarName);
|
|
SConstantBuffer *FindCB(_In_z_ LPCSTR pName);
|
|
void ReplaceCBReference(_In_ SConstantBuffer *pOldBufferBlock, _In_ ID3D11Buffer *pNewBuffer); // Used by user-managed CBs
|
|
void ReplaceSamplerReference(_In_ SSamplerBlock *pOldSamplerBlock, _In_ ID3D11SamplerState *pNewSampler);
|
|
void AddRefAllForCloning( _In_ CEffect* pEffectSource );
|
|
HRESULT CopyMemberInterfaces( _In_ CEffect* pEffectSource );
|
|
HRESULT CopyStringPool( _In_ CEffect* pEffectSource, _Inout_ CPointerMappingTable& mappingTable );
|
|
HRESULT CopyTypePool( _In_ CEffect* pEffectSource, _Inout_ CPointerMappingTable& mappingTableTypes, _Inout_ CPointerMappingTable& mappingTableStrings );
|
|
HRESULT CopyOptimizedTypePool( _In_ CEffect* pEffectSource, _Inout_ CPointerMappingTable& mappingTableTypes );
|
|
HRESULT RecreateCBs();
|
|
HRESULT FixupMemberInterface( _Inout_ SMember* pMember, _In_ CEffect* pEffectSource, _Inout_ CPointerMappingTable& mappingTableStrings );
|
|
|
|
void ValidateIndex(_In_ uint32_t Elements);
|
|
|
|
void IncrementTimer();
|
|
void HandleLocalTimerRollover();
|
|
|
|
friend struct SConstantBuffer;
|
|
|
|
public:
|
|
CEffect( uint32_t Flags = 0 );
|
|
virtual ~CEffect();
|
|
void ReleaseShaderRefection();
|
|
|
|
// Initialize must be called after the effect is created
|
|
HRESULT LoadEffect(_In_reads_bytes_(cbEffectBuffer) const void *pEffectBuffer, _In_ uint32_t cbEffectBuffer);
|
|
|
|
// Once the effect is fully loaded, call BindToDevice to attach it to a device
|
|
HRESULT BindToDevice(_In_ ID3D11Device *pDevice, _In_z_ LPCSTR srcName );
|
|
|
|
Timer GetCurrentTime() const { return m_LocalTimer; }
|
|
|
|
bool IsReflectionData(void *pData) const { return m_pReflection->m_Heap.IsInHeap(pData); }
|
|
bool IsRuntimeData(void *pData) const { return m_Heap.IsInHeap(pData); }
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Public interface
|
|
|
|
// IUnknown
|
|
STDMETHOD(QueryInterface)(REFIID iid, _COM_Outptr_ LPVOID *ppv) override;
|
|
STDMETHOD_(ULONG, AddRef)() override;
|
|
STDMETHOD_(ULONG, Release)() override;
|
|
|
|
// ID3DX11Effect
|
|
STDMETHOD_(bool, IsValid)() override { return true; }
|
|
|
|
STDMETHOD(GetDevice)(_Outptr_ ID3D11Device** ppDevice) override;
|
|
|
|
STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_DESC *pDesc) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectConstantBuffer*, GetConstantBufferByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectConstantBuffer*, GetConstantBufferByName)(_In_z_ LPCSTR Name) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetVariableByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetVariableByName)(_In_z_ LPCSTR Name) override;
|
|
STDMETHOD_(ID3DX11EffectVariable*, GetVariableBySemantic)(_In_z_ LPCSTR Semantic) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByName)(_In_z_ LPCSTR Name) override;
|
|
|
|
STDMETHOD_(ID3DX11EffectGroup*, GetGroupByIndex)(_In_ uint32_t Index) override;
|
|
STDMETHOD_(ID3DX11EffectGroup*, GetGroupByName)(_In_z_ LPCSTR Name) override;
|
|
|
|
STDMETHOD_(ID3D11ClassLinkage*, GetClassLinkage)() override;
|
|
|
|
STDMETHOD(CloneEffect)(_In_ uint32_t Flags, _Outptr_ ID3DX11Effect** ppClonedEffect) override;
|
|
STDMETHOD(Optimize)() override;
|
|
STDMETHOD_(bool, IsOptimized)() override;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// New reflection helpers
|
|
|
|
ID3DX11EffectType * CreatePooledSingleElementTypeInterface(_In_ SType *pType);
|
|
ID3DX11EffectVariable * CreatePooledVariableMemberInterface(_In_ TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity,
|
|
_In_ const SVariable *pMember,
|
|
_In_ const UDataPointer Data, _In_ bool IsSingleElement, _In_ uint32_t Index);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#pragma warning(pop)
|