示例#1
0
        /// <summary>
        /// Computes dot product of two operands.
        /// </summary>
        public Operand Dot(Operand in1, Operand in2)
        {
            if (in1.IsArray || !in1.Equals(in2))
            {
                throw new IncompatibleOperandsException("Dot operation requires both formats to be the same.");
            }

            PinFormat fmt;

            if (!PinFormatHelper.IsVector(in1.Format, out fmt))
            {
                throw new IncompatibleOperandsException("Dot operation requires both formats to be vectors.");
            }

            // We check if we can precache it, this is copy only op.
            if (in1.IsFixed && in2.IsFixed)
            {
                return(CreateFixed(fmt, in1.ArraySize, Math.MathHelper.Dot(in1.Value, in2.Value)));
            }

            // Else create temp and return.
            Operand tmp = CreateTemporary(fmt, in1.ArraySize);

            compiler.Mul(in1.Name, in2.Name, tmp.Name);
            return(tmp);
        }
示例#2
0
        protected override Pin[] CreateOutputs()
        {
            // We search for vector-* and *-vector operations.
            PinFormat scalar;

            if (PinFormatHelper.IsVector(inputs[0].Format, out scalar))
            {
                // The result must be matrix.
                return(new Pin[] { inputs[0].Clone(this) });
            }
            if (PinFormatHelper.IsVector(inputs[1].Format, out scalar))
            {
                return(new Pin[] { inputs[1].Clone(this) });
            }

            // We search for matrix-* and *-matrix operations.
            if (PinFormatHelper.IsMatrix(inputs[0].Format, out scalar))
            {
                // The result must be matrix.
                return(new Pin[] { inputs[0].Clone(this) });
            }
            if (PinFormatHelper.IsMatrix(inputs[1].Format, out scalar))
            {
                // The result must be matrix.
                return(new Pin[] { inputs[1].Clone(this) });
            }

            // Must be equal, we simply output.
            return(new Pin[] { inputs[0].Clone(this) });
        }
示例#3
0
        /// <summary>
        /// Computes dot product of two operands.
        /// </summary>
        /// <returns>Result of operation.</returns>
        public void Dot(Operand in1, Operand in2, Operand outOp)
        {
            if (in1.IsArray || !in1.Equals(in2) || !outOp.IsWritable)
            {
                throw new IncompatibleOperandsException("Addition operation requires both formats to be the same.");
            }

            PinFormat fmt;

            if (!PinFormatHelper.IsVector(in1.Format, out fmt) || outOp.Format != fmt)
            {
                throw new IncompatibleOperandsException("Only vector types can be used in dot product, scalars must match vector types.");
            }

            // We check if we can precache it, this is copy only op.
            if (in1.IsFixed && in2.IsFixed)
            {
                Operand tmp = CreateFixed(in1.Format, in1.ArraySize, Math.MathHelper.Dot(in1.Value, in2.Value));

                // We must create a mem copy.
                compiler.Mov(tmp.Name, outOp.Name);

                return;
            }

            compiler.Dot(in1.Name, in2.Name, outOp.Name);
        }
示例#4
0
        /// <summary>
        /// Multiplies two operands.
        /// </summary>
        /// <returns>Result of operation.</returns>
        public void Mul(Operand in1, Operand in2, Operand outOp)
        {
            if (in1.IsArray || !in1.Equals(in2) || !in1.Equals(outOp) || !outOp.IsWritable)
            {
                throw new IncompatibleOperandsException("Addition operation requires both formats to be the same.");
            }

            // We check if we can precache it, this is copy only op.
            if (in1.IsFixed && in2.IsFixed)
            {
                Operand tmp = CreateFixed(in1.Format, in1.ArraySize, Math.MathHelper.Mul(in1.Value, in2.Value));

                // We must create a mem copy.
                compiler.Mov(tmp.Name, outOp.Name);

                return;
            }

            PinFormat dummy;

            // Special matrix-* or *-matrix multiplication.
            if (PinFormatHelper.IsMatrix(in1.Format, out dummy) ||
                PinFormatHelper.IsMatrix(in2.Format, out dummy))
            {
                compiler.MulEx(in1.Name, in2.Name, outOp.Name);
            }
            else
            {
                compiler.Mul(in1.Name, in2.Name, outOp.Name);
            }
        }
示例#5
0
        public SwizzleOperation(SwizzleMask mask)
        {
            this.mask = mask;

            inputDesc = new PinsDescriptor(
                new PinDescriptor(PinFormatHelper.ContainsComponents(mask.MinimumSwizzleInFormat), "Data to be swizzled."));
        }
示例#6
0
        /// <summary>
        /// Creates an expand operation.
        /// </summary>
        public ExpandOperation(PinFormat expandTo, ExpandType type)
        {
            this.type     = type;
            this.expandTo = expandTo;

            inputDesc = new PinsDescriptor(
                new PinDescriptor(PinFormatHelper.ExpandableTo(expandTo), "Data to be expanded."));
        }
示例#7
0
        protected override Pin[] CreateOutputs()
        {
            PinFormat scalar;

            PinFormatHelper.IsVector(inputs[0].Format, out scalar);

            // We now create result.
            return(new Pin[] { new Pin(scalar, Pin.NotArray, this) });
        }
示例#8
0
        /// <summary>
        /// Multiplies two operands.
        /// </summary>
        public Operand Mul(Operand in1, Operand in2)
        {
            // TODO: validation.

            PinFormat outFmt = in1.Format;

            // Same format.
            if (in1.Format == in2.Format)
            {
                outFmt = in1.Format;
            }
            // Matrix x vector.
            else if (in1.Format == PinFormat.Float4x4 && in2.Format == PinFormat.Floatx4)
            {
                outFmt = PinFormat.Floatx4;
            }
            // By scalar.
            else if (in1.Format == PinFormat.Float)
            {
                outFmt = in2.Format;
            }
            else if (in2.Format == PinFormat.Float)
            {
                outFmt = in1.Format;
            }
            else
            {
                throw new NotSupportedException();
            }

            // We check if we can precache it, this is copy only op.
            if (in1.IsFixed && in2.IsFixed)
            {
                return(CreateFixed(outFmt, in1.ArraySize, Math.MathHelper.Mul(in1.Value, in2.Value)));
            }



            // Else create temp and return.
            Operand   tmp = CreateTemporary(outFmt, in1.ArraySize);
            PinFormat dummy;

            // Special matrix-* or *-matrix multiplication.
            if (PinFormatHelper.IsMatrix(in1.Format, out dummy) ||
                PinFormatHelper.IsMatrix(in2.Format, out dummy))
            {
                compiler.MulEx(in1.Name, in2.Name, tmp.Name);
            }
            else
            {
                compiler.Mul(in1.Name, in2.Name, tmp.Name);
            }
            return(tmp);
        }
示例#9
0
        /// <summary>
        /// Registers parameters of interface.
        /// </summary>
        /// <param name="xname"></param>
        /// <param name="interface"></param>
        /// <returns></returns>
        public static ShaderCompiler.Operand[] RegisterInterfaceConstants(
            ShaderCompiler compiler, string xname,
            FixedShaderParameters parameters, IInterface @interface)
        {
            // We first extract interface parameters and register them
            ParameterDescription[]   descs     = @interface.AdditionalParameters;
            ShaderCompiler.Operand[] constants = new ShaderCompiler.Operand[descs.Length];
            for (int j = 0; j < descs.Length; j++)
            {
                ParameterDescription desc = descs[j];

                string name = string.Format("{0}.{1}", xname, desc.Name);

                if (desc.IsFixed)
                {
                    if (PinFormatHelper.IsTexture(desc.Pin.Format))
                    {
                        // We check the id.
                        uint regId = (uint)parameters[name];

                        constants[j] = compiler.CreateTexture(desc.Pin.Format, desc.Pin.TextureFormat, regId);
                    }
                    else if (desc.Pin.Format == PinFormat.Sampler)
                    {
                        uint regId = (uint)parameters[name];

                        constants[j] = compiler.CreateSampler(regId);
                    }
                    else
                    {
                        throw new NotImplementedException("Fixed data not yet implemented.");
                    }
                }
                else
                {
                    uint layoutID;

                    // If it is not fixed, we create constant.
                    uint offset = parameters.GetOffset(name, out layoutID);

                    constants[j] = compiler.CreateConstant(desc.Pin.Format, desc.Pin.Size, layoutID, offset);
                }
            }

            return(constants);
        }
        /// <summary>
        /// Adds element at specified offset.
        /// </summary>
        /// <param name="name">The name of parameter.</param>
        /// <param name="format">The format of parameter.</param>
        /// <param name="offset">The offset of element.</param>
        public void AddElement([NotEmpty] string name, PinFormat format, uint arraySize, uint offset)
        {
            // Validate format.
            PinFormat scalar = PinFormatHelper.ToScalar(format);

            if (scalar != PinFormat.Integer && scalar != PinFormat.Float)
            {
                throw new ArgumentException("Only Float and Integer format acceptable.");
            }

            if (data.ContainsKey(name))
            {
                throw new ArgumentException(string.Format("Name {0} is already defined.", name));
            }

            // We add element.
            ConstantBufferLayout.ParamOffset d = new ConstantBufferLayout.ParamOffset();
            d.Description = new ParameterDescription(name, new Pin(format, arraySize, null));
            d.Offset      = offset;
            data.Add(name, d);
        }
        /// <summary>
        /// We check the parameter and do it recursevelly in case of interfaces.
        /// </summary>
        /// <param name="parameter"></param>
        private bool CheckParam(ParameterDescription parameter, out string errorDesc)
        {
            errorDesc = null;

            // We first find it.
            object value;

            if (!fixedParameters.TryGetValue(parameter.Name, out value))
            {
                if (parameter.IsFixed)
                {
                    errorDesc = string.Format("Parameter {0} is not defined in fixed shader parameters and it should be.", parameter.Name);
                    return(false);
                }

                // We must locate parameter in one of constant layouts.
                foreach (ConstantBufferLayout layout in layouts)
                {
                    if (layout.IsDefined(parameter.Name))
                    {
                        return(true);
                    }
                }

                errorDesc = string.Format("Parameter {0} is not defined anywhere", parameter.Name);
                return(false);
            }

            // We first check if format is compatible and "sizes" are compatible.
            if (parameter.Pin.IsDynamicArray)
            {
                switch (parameter.Pin.Format)
                {
                case PinFormat.Texture1D:
                case PinFormat.Texture1DArray:
                case PinFormat.Texture2D:
                case PinFormat.Texture2DArray:
                case PinFormat.TextureCube:
                case PinFormat.Texture3D:
                case PinFormat.BufferTexture:
                    if (value is uint[])
                    {
                        uint[] array = (uint[])value;


                        for (int i = 0; i < array.Length; i++)
                        {
                            if (array[i] >= GraphicsDevice.MaxTexture)
                            {
                                errorDesc = string.Format("Index of texture must be in range [0,{0}) for all parameter {1}, it is not at least for index {2}",
                                                          GraphicsDevice.MaxTexture, parameter.Name, i);
                                return(false);
                            }
                        }
                    }
                    else
                    {
                        errorDesc = string.Format("Value of format for parameter {0} must be uint[] that represents position of textures", parameter.Name);
                        return(false);
                    }
                    break;

                case PinFormat.Sampler:
                    if (value is uint[])
                    {
                        uint[] array = (uint[])value;

                        for (int i = 0; i < array.Length; i++)
                        {
                            if ((uint)array[i] >= GraphicsDevice.MaxStateObjectsPerType)
                            {
                                errorDesc = string.Format("Index of sampler state must be in range [0,{0}) for parameter {1}, index {2}",
                                                          GraphicsDevice.MaxTexture, parameter.Name, i);
                                return(false);
                            }
                        }
                    }
                    else
                    {
                        errorDesc = string.Format("Value of format for parameter {0} must be uint that represents positions of samplers", parameter.Name);
                        return(false);
                    }
                    break;

                case PinFormat.Interface:
                    if (value is IInterface[])
                    {
                        IInterface[] array = value as IInterface[];


                        for (int i = 0; i < array.Length; i++)
                        {
                            // We check consistency of interface when compiled (more efficient).
                            foreach (ParameterDescription d in array[i].AdditionalParameters)
                            {
                                // We first "scope" the parameter.
                                ParameterDescription d2 = ParameterDescription.ScopeParameter(parameter.Name, i, d);

                                // Now we search for it (validate it).
                                if (!CheckParam(d2, out errorDesc))
                                {
                                    return(false);
                                }
                            }
                        }
                    }
                    else
                    {
                        errorDesc = string.Format("The parameter {0} is not an interface array. All parameters must be filled in IInterface[] (and not other base type).", parameter.Name);
                        return(false);
                    }

                    break;

                default:
                    uint arraySize;
                    // For all others, we check type consistency.
                    if (!PinFormatHelper.IsCompatibleArray(parameter.Pin.Format, value, out arraySize))
                    {
                        errorDesc = string.Format("Array parameter {0} with format {1} is not compatible with value {2}", parameter.Name, parameter.Pin.Format, value);
                        return(false);
                    }

                    // We check if array length is ok.
                    object va;
                    if (fixedParameters.TryGetValue(parameter.Name + ".length", out va) && (va is uint))
                    {
                        if ((uint)va != arraySize)
                        {
                            errorDesc = string.Format("Array size {0} for parameter {1} needn't be specified, but it is specified and it is {2} - not consistant.",
                                                      arraySize, parameter.Name, va);
                            return(false);
                        }
                    }
                    break;
                }
            }
            else if (parameter.Pin.IsStaticArray)
            {
                switch (parameter.Pin.Format)
                {
                case PinFormat.Texture1D:
                case PinFormat.BufferTexture:
                case PinFormat.Texture1DArray:
                case PinFormat.Texture2D:
                case PinFormat.Texture2DArray:
                case PinFormat.TextureCube:
                case PinFormat.Texture3D:
                    if (value is uint[])
                    {
                        uint[] array = (uint[])value;

                        if (array.Length != parameter.Pin.Size)
                        {
                            errorDesc = string.Format("The length of array of parameter {0} is {1} but should be {2}", parameter.Name, array.Length, parameter.Pin.Size);
                            return(false);
                        }

                        for (int i = 0; i < array.Length; i++)
                        {
                            if (array[i] >= GraphicsDevice.MaxTexture)
                            {
                                errorDesc = string.Format("Index of texture must be in range [0,{0}) for all parameter {1}, it is not at least for index {2}",
                                                          GraphicsDevice.MaxTexture, parameter.Name, i);
                                return(false);
                            }
                        }
                    }
                    else
                    {
                        errorDesc = string.Format("Value of format for parameter {0} must be uint[] that represents position of textures", parameter.Name);
                        return(false);
                    }
                    break;

                case PinFormat.Sampler:
                    if (value is uint[])
                    {
                        uint[] array = (uint[])value;

                        if (array.Length != parameter.Pin.Size)
                        {
                            errorDesc = string.Format("The length of array of parameter {0} is {1} but should be {2}", parameter.Name, array.Length, parameter.Pin.Size);
                            return(false);
                        }

                        for (int i = 0; i < array.Length; i++)
                        {
                            if ((uint)array[i] >= GraphicsDevice.MaxStateObjectsPerType)
                            {
                                errorDesc = string.Format("Index of sampler state must be in range [0,{0}) for parameter {1}, index {2}",
                                                          GraphicsDevice.MaxTexture, parameter.Name, i);
                                return(false);
                            }
                        }
                    }
                    else
                    {
                        errorDesc = string.Format("Value of format for parameter {0} must be uint that represents positions of samplers", parameter.Name);
                        return(false);
                    }
                    break;

                case PinFormat.Interface:
                    if (value is IInterface[])
                    {
                        IInterface[] array = value as IInterface[];

                        if (array.Length != parameter.Pin.Size)
                        {
                            errorDesc = string.Format("The length of array of parameter {0} is {1} but should be {2}", parameter.Name, array.Length, parameter.Pin.Size);
                            return(false);
                        }

                        for (int i = 0; i < array.Length; i++)
                        {
                            // We check consistency of interface when compiled (more efficient).
                            foreach (ParameterDescription d in array[i].AdditionalParameters)
                            {
                                // We first "scope" the parameter.
                                ParameterDescription d2 = ParameterDescription.ScopeParameter(parameter.Name, d);

                                // Now we search for it (validate it).
                                if (!CheckParam(d2, out errorDesc))
                                {
                                    return(false);
                                }
                            }
                        }
                    }
                    else
                    {
                        errorDesc = string.Format("The parameter {0} is not an interface array. All parameters must be filled in IInterface[] (and not other base type).", parameter.Name);
                        return(false);
                    }

                    break;

                default:

                    uint arraySize;
                    // For all others, we check type consistency.
                    if (!PinFormatHelper.IsCompatibleArray(parameter.Pin.Format, value, out arraySize))
                    {
                        errorDesc = string.Format("Array parameter {0} with format {1} is not compatible with value {2}", parameter.Name, parameter.Pin.Format, value);
                        return(false);
                    }

                    // We check if array length is ok.
                    if (arraySize != parameter.Pin.Size)
                    {
                        errorDesc = string.Format("Parameter {0} with array size {1} is expected to be of size {2}", parameter.Name, arraySize, parameter.Pin.Size);
                        return(false);
                    }
                    break;
                }
            }
            else
            {
                switch (parameter.Pin.Format)
                {
                case PinFormat.Texture1D:
                case PinFormat.BufferTexture:
                case PinFormat.Texture1DArray:
                case PinFormat.Texture2D:
                case PinFormat.Texture2DArray:
                case PinFormat.TextureCube:
                case PinFormat.Texture3D:
                    if (value is uint)
                    {
                        if ((uint)value >= GraphicsDevice.MaxTexture)
                        {
                            errorDesc = string.Format("Index of texture must be in range [0,{0}) for parameter {1}", GraphicsDevice.MaxTexture, parameter.Name);
                            return(false);
                        }
                    }
                    else
                    {
                        errorDesc = string.Format("Value of format for parameter {0} must be uint that represents position of texture", parameter.Name);
                        return(false);
                    }
                    break;

                case PinFormat.Sampler:
                    if (value is uint)
                    {
                        if ((uint)value >= GraphicsDevice.MaxStateObjectsPerType)
                        {
                            errorDesc = string.Format("Index of sampler state must be in range [0,{0}) for parameter {1}", GraphicsDevice.MaxTexture, parameter.Name);
                            return(false);
                        }
                    }
                    else
                    {
                        errorDesc = string.Format("Value of format for parameter {0} must be uint that represents position of sampler", parameter.Name);
                        return(false);
                    }
                    break;

                case PinFormat.Interface:
                    if (value is IInterface)
                    {
                        IInterface ivalue = value as IInterface;

                        // We check consistency of interface when compiled (more efficient).
                        foreach (ParameterDescription d in ivalue.AdditionalParameters)
                        {
                            // We first "scope" the parameter.
                            ParameterDescription d2 = ParameterDescription.ScopeParameter(parameter.Name, d);

                            // Now we search for it (validate it).
                            if (!CheckParam(d2, out errorDesc))
                            {
                                return(false);
                            }
                        }
                    }
                    else
                    {
                        errorDesc = string.Format("The parameter {0} is not an interface (does not extend IInterface)", parameter.Name);
                        return(false);
                    }

                    break;

                default:
                    // For all others, we check type consistency.
                    if (!PinFormatHelper.IsCompatible(parameter.Pin.Format, value))
                    {
                        errorDesc = string.Format("Parameter {0} with format {1} is not compatible with value {2}", parameter.Name, parameter.Pin.Format, value);
                        return(false);
                    }
                    break;
                }
            }


            return(true);
        }
 /// <summary>
 /// Appends element to format.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="format"></param>
 public void AppendElement([NotEmpty] string name, PinFormat format, uint arraySize)
 {
     currentOffset = PinFormatHelper.Align(format, currentOffset);
     AddElement(name, format, Pin.NotArray, currentOffset);
     currentOffset += PinFormatHelper.Advance(format, arraySize);
 }