Beispiel #1
0
        public static void CompareVariable(EffectVariable reflectionVariable, object variable)
        {
            EffectTypeDescription typeDesc = reflectionVariable.TypeInfo.Description;

            Assert.AreEqual(typeDesc.TypeName, typeDesc.TypeName);
            Assert.AreEqual(typeDesc.Class, typeDesc.Class);
            Assert.AreEqual(typeDesc.Type, typeDesc.Type);
            Assert.AreEqual(typeDesc.Elements, typeDesc.Elements);
            Assert.AreEqual(typeDesc.Members, typeDesc.Members);
            Assert.AreEqual(typeDesc.Rows, typeDesc.Rows);
            Assert.AreEqual(typeDesc.Columns, typeDesc.Columns);
            Assert.AreEqual(typeDesc.PackedSize, typeDesc.PackedSize);
            Assert.AreEqual(typeDesc.UnpackedSize, typeDesc.UnpackedSize);
            Assert.AreEqual(typeDesc.Stride, typeDesc.Stride);
            EffectVariableDescription variableDesc = reflectionVariable.Description;

            Assert.AreEqual(variableDesc.Name, variableDesc.Name);
            Assert.AreEqual(variableDesc.Semantic, variableDesc.Semantic);
            Assert.AreEqual(variableDesc.Flags, variableDesc.Flags);
            Assert.AreEqual(variableDesc.AnnotationCount, variableDesc.AnnotationCount);
            Assert.AreEqual(variableDesc.BufferOffset, variableDesc.BufferOffset);
            Assert.AreEqual(variableDesc.ExplicitBindPoint, variableDesc.ExplicitBindPoint);

            if (variable is EffectNumericVariable v1)
            {
                Assert.AreEqual(variableDesc.Name, v1.Name);
                Assert.AreEqual(0, v1.ExplicitBindPoint);
            }
            if (variable is EffectObjectVariable v2)
            {
                Assert.AreEqual(variableDesc.Name, v2.Name);
            }

            for (int i = 0; i < variableDesc.AnnotationCount; i++)
            {
                var annotation = reflectionVariable.GetAnnotationByIndex(i);
            }
            if (typeDesc.Type == ShaderVariableType.Sampler)
            {
                EffectSamplerVariable sampVariable = reflectionVariable.AsSampler();
                SamplerState          samplerState = sampVariable.GetSampler();
                var sampDesc = samplerState.Description;
            }
        }
Beispiel #2
0
        private static void HashType(ObjectIdBuilder hashBuilder, EffectTypeDescription type)
        {
            hashBuilder.Write(type.RowCount);
            hashBuilder.Write(type.ColumnCount);
            hashBuilder.Write(type.Elements);
            if (type.Name != null)
            {
                hashBuilder.Write(type.Name);
            }

            if (type.Members != null)
            {
                foreach (var member in type.Members)
                {
                    hashBuilder.Write(member.Name);
                    hashBuilder.Write(member.Offset);
                    HashType(hashBuilder, member.Type);
                }
            }
        }
Beispiel #3
0
        private static int ComputeMemberSize(ref EffectTypeDescription memberType, ref int constantBufferOffset)
        {
            var elementSize = ComputeTypeSize(memberType.Type);
            int size;
            int alignment = 4;

            switch (memberType.Class)
            {
            case EffectParameterClass.Struct:
            {
                // Fill members
                size = 0;
                for (int index = 0; index < memberType.Members.Length; index++)
                {
                    // Properly compute size and offset according to DX rules
                    var memberSize = ComputeMemberSize(ref memberType.Members[index].Type, ref size);

                    // Align offset and store it as member offset
                    memberType.Members[index].Offset = size;

                    // Adjust offset for next item
                    size += memberSize;
                }

                alignment = size;
                break;
            }

            case EffectParameterClass.Scalar:
            {
                size = elementSize;
                break;
            }

            case EffectParameterClass.Color:
            case EffectParameterClass.Vector:
            {
                size = elementSize * memberType.ColumnCount;
                break;
            }

            case EffectParameterClass.MatrixColumns:
            {
                size = elementSize * (4 * (memberType.ColumnCount - 1) + memberType.RowCount);
                break;
            }

            case EffectParameterClass.MatrixRows:
            {
                size = elementSize * (4 * (memberType.RowCount - 1) + memberType.ColumnCount);
                break;
            }

            default:
                throw new NotImplementedException();
            }

            // Update element size
            memberType.ElementSize = size;

            // Array
            if (memberType.Elements > 0)
            {
                var roundedSize = (size + 15) / 16 * 16; // Round up to vec4
                size     += roundedSize * (memberType.Elements - 1);
                alignment = 16;
            }

            // Align to float4 if it is bigger than leftover space in current float4
            if (constantBufferOffset / 16 != (constantBufferOffset + size - 1) / 16)
            {
                alignment = 16;
            }

            // Align offset and store it as member offset
            constantBufferOffset = (constantBufferOffset + alignment - 1) / alignment * alignment;

            return(size);
        }
Beispiel #4
0
        private static EffectTypeDescription CreateTypeInfo(TypeBase variableType, List <AttributeBase> attributes, out EffectTypeDescription elementType)
        {
            elementType = default;

            var parameterTypeInfo = new EffectTypeDescription();

            if (variableType.TypeInference.TargetType != null)
            {
                variableType = variableType.TypeInference.TargetType;
            }

            if (variableType is ArrayType)
            {
                var arrayType = (ArrayType)variableType;
                variableType = arrayType.Type;
                parameterTypeInfo.Elements = (int)((LiteralExpression)arrayType.Dimensions[0]).Literal.Value;

                if (variableType.TypeInference.TargetType != null)
                {
                    variableType = variableType.TypeInference.TargetType;
                }
            }

            if (variableType is ScalarType)
            {
                if (variableType == ScalarType.Int)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Scalar;
                    parameterTypeInfo.Type  = EffectParameterType.Int;
                }
                else if (variableType == ScalarType.UInt)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Scalar;
                    parameterTypeInfo.Type  = EffectParameterType.UInt;
                }
                else if (variableType == ScalarType.Float)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Scalar;
                    parameterTypeInfo.Type  = EffectParameterType.Float;
                }
                else if (variableType == ScalarType.Double)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Scalar;
                    parameterTypeInfo.Type  = EffectParameterType.Double;
                }
                else if (variableType == ScalarType.Bool)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Scalar;
                    parameterTypeInfo.Type  = EffectParameterType.Bool;
                }

                parameterTypeInfo.RowCount    = 1;
                parameterTypeInfo.ColumnCount = 1;
            }
            else if (variableType is VectorType vectorType)
            {
                if (vectorType.Type == ScalarType.Float)
                {
                    bool isColor = attributes.OfType <AttributeDeclaration>().Any(x => x.Name == "Color");
                    parameterTypeInfo.Class = isColor ? EffectParameterClass.Color : EffectParameterClass.Vector;
                    parameterTypeInfo.Type  = EffectParameterType.Float;
                }
                else if (vectorType.Type == ScalarType.Double)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Vector;
                    parameterTypeInfo.Type  = EffectParameterType.Double;
                }
                else if (vectorType.Type == ScalarType.Int)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Vector;
                    parameterTypeInfo.Type  = EffectParameterType.Int;
                }
                else if (vectorType.Type == ScalarType.UInt)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Vector;
                    parameterTypeInfo.Type  = EffectParameterType.UInt;
                }

                parameterTypeInfo.RowCount    = 1;
                parameterTypeInfo.ColumnCount = ((VectorType)variableType).Dimension;
            }
            else if (variableType is MatrixType)
            {
                parameterTypeInfo.Class       = EffectParameterClass.MatrixColumns;
                parameterTypeInfo.Type        = EffectParameterType.Float;
                parameterTypeInfo.RowCount    = ((MatrixType)variableType).RowCount;
                parameterTypeInfo.ColumnCount = ((MatrixType)variableType).ColumnCount;
            }
            else if (variableType is StructType)
            {
                var structType = (StructType)variableType;

                parameterTypeInfo.Class       = EffectParameterClass.Struct;
                parameterTypeInfo.RowCount    = 1;
                parameterTypeInfo.ColumnCount = 1;
                parameterTypeInfo.Name        = structType.Name.Text;

                var members = new List <EffectTypeMemberDescription>();
                foreach (var field in structType.Fields)
                {
                    var memberInfo = new EffectTypeMemberDescription
                    {
                        Name = field.Name.Text,
                        Type = CreateTypeInfo(field.Type, field.Attributes, out var _),
                    };
                    members.Add(memberInfo);
                }

                parameterTypeInfo.Members = members.ToArray();
            }
            else
            {
                var variableTypeName = variableType.Name.Text.ToLowerInvariant();

                if (variableType is ClassType classType && classType.GenericArguments.Count == 1)
                {
                    elementType = CreateTypeInfo(classType.GenericArguments[0], new List <AttributeBase>(), out var _);
                }

                switch (variableTypeName)
                {
                case "cbuffer":
                    parameterTypeInfo.Class = EffectParameterClass.ConstantBuffer;
                    parameterTypeInfo.Type  = EffectParameterType.ConstantBuffer;
                    break;

                case "tbuffer":
                    parameterTypeInfo.Class = EffectParameterClass.TextureBuffer;
                    parameterTypeInfo.Type  = EffectParameterType.TextureBuffer;
                    break;

                case "structuredbuffer":
                    parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                    parameterTypeInfo.Type  = EffectParameterType.StructuredBuffer;
                    break;

                case "rwstructuredbuffer":
                    parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                    parameterTypeInfo.Type  = EffectParameterType.RWStructuredBuffer;
                    break;

                case "consumestructuredbuffer":
                    parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                    parameterTypeInfo.Type  = EffectParameterType.ConsumeStructuredBuffer;
                    break;

                case "appendstructuredbuffer":
                    parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                    parameterTypeInfo.Type  = EffectParameterType.AppendStructuredBuffer;
                    break;

                case "buffer":
                    parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                    parameterTypeInfo.Type  = EffectParameterType.Buffer;
                    break;

                case "rwbuffer":
                    parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                    parameterTypeInfo.Type  = EffectParameterType.RWBuffer;
                    break;

                case "byteaddressbuffer":
                    parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                    parameterTypeInfo.Type  = EffectParameterType.ByteAddressBuffer;
                    break;

                case "rwbyteaddressbuffer":
                    parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                    parameterTypeInfo.Type  = EffectParameterType.RWByteAddressBuffer;
                    break;

                case "texture1d":
                    parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                    parameterTypeInfo.Type  = EffectParameterType.Texture1D;
                    break;

                case "texturecube":
                    parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                    parameterTypeInfo.Type  = EffectParameterType.TextureCube;
                    break;

                case "texture2d":
                    parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                    parameterTypeInfo.Type  = EffectParameterType.Texture2D;
                    break;

                case "texture2dms":
                    parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                    parameterTypeInfo.Type  = EffectParameterType.Texture2DMultisampled;
                    break;

                case "texture3d":
                    parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                    parameterTypeInfo.Type  = EffectParameterType.Texture3D;
                    break;

                case "texture1darray":
                    parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                    parameterTypeInfo.Type  = EffectParameterType.Texture1DArray;
                    break;

                case "texturecubearray":
                    parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                    parameterTypeInfo.Type  = EffectParameterType.TextureCubeArray;
                    break;

                case "texture2darray":
                    parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                    parameterTypeInfo.Type  = EffectParameterType.Texture2DArray;
                    break;

                case "texture2dmsarray":
                    parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                    parameterTypeInfo.Type  = EffectParameterType.Texture2DMultisampledArray;
                    break;

                case "rwtexture1d":
                    parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                    parameterTypeInfo.Type  = EffectParameterType.RWTexture1D;
                    break;

                case "rwtexture2d":
                    parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                    parameterTypeInfo.Type  = EffectParameterType.RWTexture2D;
                    break;

                case "rwtexture3d":
                    parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                    parameterTypeInfo.Type  = EffectParameterType.RWTexture3D;
                    break;

                case "rwtexture1darray":
                    parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                    parameterTypeInfo.Type  = EffectParameterType.RWTexture1DArray;
                    break;

                case "rwtexture2darray":
                    parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                    parameterTypeInfo.Type  = EffectParameterType.RWTexture2DArray;
                    break;

                case "samplerstate":
                case "samplercomparisonstate":
                    parameterTypeInfo.Class = EffectParameterClass.Sampler;
                    parameterTypeInfo.Type  = EffectParameterType.Sampler;
                    break;
                }
            }

            return(parameterTypeInfo);
        }
Beispiel #5
0
        public static void CompareVariable(EffectVariable reflectionVariable, Fx10.IEffectVariable variable)
        {
            EffectTypeDescription typeDesc = reflectionVariable.TypeInfo.Description;
            var type = variable.Type;

            Assert.AreEqual(typeDesc.TypeName, type.TypeName);
            Assert.AreEqual(typeDesc.Class, (ShaderVariableClass)type.VariableClass);
            Assert.AreEqual(typeDesc.Type, (ShaderVariableType)type.VariableType);
            Assert.AreEqual(typeDesc.Elements, type.ElementCount);
            Assert.AreEqual(typeDesc.Members, type.MemberCount);
            Assert.AreEqual(typeDesc.Rows, type.Rows);
            Assert.AreEqual(typeDesc.Columns, type.Columns);
            Assert.AreEqual(typeDesc.PackedSize, type.PackedSize);
            Assert.AreEqual(typeDesc.UnpackedSize, type.UnpackedSize);
            Assert.AreEqual(typeDesc.Stride, type.Stride);
            EffectVariableDescription variableDesc = reflectionVariable.Description;

            Assert.AreEqual(variableDesc.Name, variable.Name);
            Assert.AreEqual(variableDesc.Semantic ?? "", variable.Semantic);
            Assert.AreEqual(variableDesc.Flags, (EffectVariableFlags)variable.Flags);
            Assert.AreEqual(variableDesc.AnnotationCount, variable.AnnotationCount);
            //TODO: SharpDX seems defines BufferOffset relative to buffer, but variable is just relative to struct
            //Assert.AreEqual(variableDesc.BufferOffset, variable.BufferOffset == uint.MaxValue ? 0 : variable.BufferOffset);
            Assert.AreEqual(variableDesc.ExplicitBindPoint, variable.ExplicitBindPoint);
            var annotations = GetAnnotations(reflectionVariable);

            if (typeDesc.Class == ShaderVariableClass.Struct)
            {
                //TODO: SharpDx has GetMemberValues on the EffectType.
                for (int i = 0; i < typeDesc.Members; i++)
                {
                    var reflectionMember = reflectionVariable.GetMemberByIndex(i);
                    var member           = variable.Type.Members[i];
                    CompareVariable(reflectionMember, member);
                }
            }
            for (int i = 0; i < annotations.Count; i++)
            {
                var reflectionAnnotation = annotations[i];
                var annotation           = variable.Annotations[i];
                CompareVariable(reflectionAnnotation, annotation);
            }
            if (typeDesc.Type == ShaderVariableType.Blend)
            {
                var specDesc = reflectionVariable
                               .AsBlend()
                               .GetBlendState()
                               .Description;
            }
            if (typeDesc.Type == ShaderVariableType.ConstantBuffer)
            {
                var specDesc = reflectionVariable
                               .AsConstantBuffer()
                               .GetConstantBuffer()
                               .Description;
            }
            if (typeDesc.Type == ShaderVariableType.DepthStencil)
            {
                var specDesc = reflectionVariable
                               .AsDepthStencil()
                               .GetDepthStencilState()
                               .Description;
            }
            if (typeDesc.Type == ShaderVariableType.DepthStencilView)
            {
                var specDesc = reflectionVariable
                               .AsDepthStencilView()
                               .GetDepthStencil()
                               .Description;
            }
            if (typeDesc.Type == ShaderVariableType.Rasterizer)
            {
                var specDesc = reflectionVariable
                               .AsRasterizer()
                               .GetRasterizerState()
                               .Description;
            }
            if (typeDesc.Type == ShaderVariableType.Rasterizer)
            {
                var specDesc = reflectionVariable
                               .AsRasterizer()
                               .GetRasterizerState()
                               .Description;
            }
            if (typeDesc.Type == ShaderVariableType.RenderTargetView)
            {
                var specDesc = reflectionVariable
                               .AsRenderTargetView()
                               .GetRenderTarget()
                               .Description;
            }
            if (typeDesc.Type == ShaderVariableType.Sampler)
            {
                var specDesc = reflectionVariable
                               .AsSampler()
                               .GetSampler()
                               .Description;
                var stateAnnotations = (variable as Fx10.EffectObjectVariable).Assignments;
            }
            if (typeDesc.Type == ShaderVariableType.PixelShader ||
                typeDesc.Type == ShaderVariableType.VertexShader ||
                typeDesc.Type == ShaderVariableType.GeometryShader)
            {
                var shader = reflectionVariable
                             .AsShader();
            }
            if (false)
            {
                var shader = reflectionVariable
                             .AsShaderResource();
            }
        }
        private static EffectTypeDescription CreateTypeInfo(TypeBase variableType, List<AttributeBase> attributes)
        {
            var parameterTypeInfo = new EffectTypeDescription();

            if (variableType.TypeInference.TargetType != null)
                variableType = variableType.TypeInference.TargetType;

            if (variableType is ArrayType)
            {
                var arrayType = (ArrayType)variableType;
                variableType = arrayType.Type;
                parameterTypeInfo.Elements = (int)((LiteralExpression)arrayType.Dimensions[0]).Literal.Value;

                if (variableType.TypeInference.TargetType != null)
                    variableType = variableType.TypeInference.TargetType;
            }

            if (variableType is ScalarType)
            {
                // Uint and int are collapsed to int
                if (variableType == ScalarType.Int || variableType == ScalarType.UInt)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Scalar;
                    parameterTypeInfo.Type = variableType == ScalarType.Int ? EffectParameterType.Int : EffectParameterType.UInt;
                }
                else if (variableType == ScalarType.Float)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Scalar;
                    parameterTypeInfo.Type = EffectParameterType.Float;
                }
                else if (variableType == ScalarType.Bool)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Scalar;
                    parameterTypeInfo.Type = EffectParameterType.Bool;
                }

                parameterTypeInfo.RowCount = 1;
                parameterTypeInfo.ColumnCount = 1;
            }
            else if (variableType is VectorType)
            {
                if (variableType == VectorType.Float2 || variableType == VectorType.Float3 || variableType == VectorType.Float4)
                {
                    bool isColor = attributes.OfType<AttributeDeclaration>().Any(x => x.Name == "Color");
                    parameterTypeInfo.Class = isColor ? EffectParameterClass.Color : EffectParameterClass.Vector;
                    parameterTypeInfo.Type = EffectParameterType.Float;
                }
                else if (variableType == VectorType.Int2 || variableType == VectorType.Int3 || variableType == VectorType.Int4)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Vector;
                    parameterTypeInfo.Type = EffectParameterType.Int;
                }
                else if (variableType == VectorType.UInt2 || variableType == VectorType.UInt3 || variableType == VectorType.UInt4)
                {
                    parameterTypeInfo.Class = EffectParameterClass.Vector;
                    parameterTypeInfo.Type = EffectParameterType.UInt;
                }

                parameterTypeInfo.RowCount = 1;
                parameterTypeInfo.ColumnCount = ((VectorType)variableType).Dimension;
            }
            else if (variableType is MatrixType)
            {
                parameterTypeInfo.Class = EffectParameterClass.MatrixColumns;
                parameterTypeInfo.Type = EffectParameterType.Float;
                parameterTypeInfo.RowCount = ((MatrixType)variableType).RowCount;
                parameterTypeInfo.ColumnCount = ((MatrixType)variableType).ColumnCount;
            }
            else if (variableType is StructType)
            {
                var structType = (StructType)variableType;

                parameterTypeInfo.Class = EffectParameterClass.Struct;
                parameterTypeInfo.RowCount = 1;
                parameterTypeInfo.ColumnCount = 1;
                parameterTypeInfo.Name = structType.Name.Text;

                var members = new List<EffectTypeMemberDescription>();
                foreach (var field in structType.Fields)
                {
                    var memberInfo = new EffectTypeMemberDescription
                    {
                        Name = field.Name.Text,
                        Type = CreateTypeInfo(field.Type, field.Attributes),
                    };
                    members.Add(memberInfo);
                }

                parameterTypeInfo.Members = members.ToArray();
            }
            else
            {
                var variableTypeName = variableType.Name.Text.ToLower();

                switch (variableTypeName)
                {
                    case "cbuffer":
                        parameterTypeInfo.Class = EffectParameterClass.ConstantBuffer;
                        parameterTypeInfo.Type = EffectParameterType.ConstantBuffer;
                        break;

                    case "tbuffer":
                        parameterTypeInfo.Class = EffectParameterClass.TextureBuffer;
                        parameterTypeInfo.Type = EffectParameterType.TextureBuffer;
                        break;

                    case "structuredbuffer":
                        parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                        parameterTypeInfo.Type = EffectParameterType.StructuredBuffer;
                        break;
                    case "rwstructuredbuffer":
                        parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                        parameterTypeInfo.Type = EffectParameterType.RWStructuredBuffer;
                        break;
                    case "consumestructuredbuffer":
                        parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                        parameterTypeInfo.Type = EffectParameterType.ConsumeStructuredBuffer;
                        break;
                    case "appendstructuredbuffer":
                        parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                        parameterTypeInfo.Type = EffectParameterType.AppendStructuredBuffer;
                        break;
                    case "buffer":
                        parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                        parameterTypeInfo.Type = EffectParameterType.Buffer;
                        break;
                    case "rwbuffer":
                        parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                        parameterTypeInfo.Type = EffectParameterType.RWBuffer;
                        break;
                    case "byteaddressbuffer":
                        parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                        parameterTypeInfo.Type = EffectParameterType.ByteAddressBuffer;
                        break;
                    case "rwbyteaddressbuffer":
                        parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                        parameterTypeInfo.Type = EffectParameterType.RWByteAddressBuffer;
                        break;

                    case "texture1d":
                        parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                        parameterTypeInfo.Type = EffectParameterType.Texture1D;
                        break;

                    case "texturecube":
                        parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                        parameterTypeInfo.Type = EffectParameterType.TextureCube;
                        break;

                    case "texture2d":
                        parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                        parameterTypeInfo.Type = EffectParameterType.Texture2D;
                        break;

                    case "texture3d":
                        parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                        parameterTypeInfo.Type = EffectParameterType.Texture3D;
                        break;

                    case "texture1darray":
                        parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                        parameterTypeInfo.Type = EffectParameterType.Texture1DArray;
                        break;

                    case "texturecubearray":
                        parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                        parameterTypeInfo.Type = EffectParameterType.TextureCubeArray;
                        break;

                    case "texture2darray":
                        parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView;
                        parameterTypeInfo.Type = EffectParameterType.Texture2DArray;
                        break;

                    case "rwtexture1d":
                        parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                        parameterTypeInfo.Type = EffectParameterType.RWTexture1D;
                        break;

                    case "rwtexture2d":
                        parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                        parameterTypeInfo.Type = EffectParameterType.RWTexture2D;
                        break;

                    case "rwtexture3d":
                        parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                        parameterTypeInfo.Type = EffectParameterType.RWTexture3D;
                        break;

                    case "rwtexture1darray":
                        parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                        parameterTypeInfo.Type = EffectParameterType.RWTexture1DArray;
                        break;

                    case "rwtexture2darray":
                        parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView;
                        parameterTypeInfo.Type = EffectParameterType.RWTexture2DArray;
                        break;

                    case "samplerstate":
                    case "samplercomparisonstate":
                        parameterTypeInfo.Class = EffectParameterClass.Sampler;
                        parameterTypeInfo.Type = EffectParameterType.Sampler;
                        break;
                }
            }

            return parameterTypeInfo;
        }
        private static int ComputeMemberSize(ref EffectTypeDescription memberType, ref int constantBufferOffset)
        {
            var elementSize = ComputeTypeSize(memberType.Type);
            int size;
            int alignment = 4;

            switch (memberType.Class)
            {
                case EffectParameterClass.Struct:
                    {
                        // Fill members
                        size = 0;
                        for (int index = 0; index < memberType.Members.Length; index++)
                        {
                            // Properly compute size and offset according to DX rules
                            var memberSize = ComputeMemberSize(ref memberType.Members[index].Type, ref size);

                            // Align offset and store it as member offset
                            memberType.Members[index].Offset = size;

                            // Adjust offset for next item
                            size += memberSize;
                        }

                        alignment = size;
                        break;
                    }
                case EffectParameterClass.Scalar:
                    {
                        size = elementSize;
                        break;
                    }
                case EffectParameterClass.Color:
                case EffectParameterClass.Vector:
                    {
                        size = elementSize * memberType.ColumnCount;
                        break;
                    }
                case EffectParameterClass.MatrixColumns:
                    {
                        size = elementSize * (4 * (memberType.ColumnCount - 1) + memberType.RowCount);
                        break;
                    }
                case EffectParameterClass.MatrixRows:
                    {
                        size = elementSize * (4 * (memberType.RowCount - 1) + memberType.ColumnCount);
                        break;
                    }
                default:
                    throw new NotImplementedException();
            }

            // Update element size
            memberType.ElementSize = size;

            // Array
            if (memberType.Elements > 0)
            {
                var roundedSize = (size + 15) / 16 * 16; // Round up to vec4
                size += roundedSize * (memberType.Elements - 1);
                alignment = 16;
            }

            // Align to float4 if it is bigger than leftover space in current float4
            if (constantBufferOffset / 16 != (constantBufferOffset + size - 1) / 16)
                alignment = 16;

            // Align offset and store it as member offset
            constantBufferOffset = (constantBufferOffset + alignment - 1) / alignment * alignment;

            return size;
        }