public override ShaderCompiler.Operand[] Compile(
            ShaderCompiler compiler, ShaderCompiler.Operand[] operands,
            FixedShaderParameters parameters, ref DualShareContext shareContext)
        {
            // We resolve interface arrays.
            object[] interfaces = InterfaceHelper.ResolveInterfaceArray(inputs[1], parameters);

            Dictionary <ICompositeInterface, ShaderCompiler.Operand[]> constants
                = new Dictionary <ICompositeInterface, ShaderCompiler.Operand[]>(interfaces.Length);

            // We extract interface parameters and register them.
            for (int i = 0; i < interfaces.Length; i++)
            {
                ICompositeInterface provider = interfaces[i] as ICompositeInterface;

                // We now register it.
                constants.Add(provider, InterfaceHelper.RegisterInterfaceConstants(compiler,
                                                                                   string.Format("Composite[{0}]", i), parameters, interfaces[i] as ICompositeInterface));
            }

            // We only need to execute last element.
            ICompositeInterface pixelProvider = interfaces[interfaces.Length - 1] as ICompositeInterface;

            // We execute it.
            return(new ShaderCompiler.Operand[] {
                pixelProvider.GetPixel(compiler, operands[0], constants)
            });
        }
Beispiel #2
0
        public override ShaderCompiler.Operand[] Compile(ShaderCompiler compiler, ShaderCompiler.Operand[] operands, FixedShaderParameters parameters, ref DualShareContext shareContext)
        {
            // We prepare operands.
            ShaderCompiler.Operand[] ret = new ShaderCompiler.Operand[operands.Length];
            for (int i = 1; i < ret.Length; i++)
            {
                ret[i] = compiler.CreateTemporary(operands[i].Format, operands[i].ArraySize);
                compiler.Mov(operands[i], ret[i]);
            }

            // At index 0, we have indexer, we initialize to 0.
            ret[0] = compiler.CreateTemporary(PinFormat.UInteger, Pin.NotArray);
            compiler.Mov(compiler.CreateFixed(PinFormat.UInteger, Pin.NotArray, (uint)0), ret[0]);

            // We begin while.
            compiler.BeginWhile();

            // We exit if iteration count is exceeded.
            compiler.Break(compiler.Compare(CompareFunction.Less, ret[0], operands[0]));
            compiler.Add(ret[0], compiler.CreateFixed(PinFormat.UInteger, Pin.NotArray, (uint)1), ret[0]);

            // We also fill dual share context.
            ShaderCompiler.Operand[] shared = new ShaderCompiler.Operand[ret.Length - 1];
            for (int i = 1; i < ret.Length; i++)
            {
                shared[i - 1] = ret[i];
            }

            shareContext = new DualShareContext(shared, parent.outputOperation);

            // We now go forward.
            return(ret);
        }
Beispiel #3
0
        public override ShaderCompiler.Operand[] Compile(ShaderCompiler compiler, ShaderCompiler.Operand[] operands, FixedShaderParameters parameters, ref DualShareContext shareContext)
        {
            // We prepare operands.
            ShaderCompiler.Operand[] ret = new ShaderCompiler.Operand[operands.Length];
            for (int i = 0; i < ret.Length; i++)
            {
                ret[i] = compiler.CreateTemporary(operands[i].Format, operands[i].ArraySize);
                compiler.Mov(operands[i], ret[i]);
            }

            // We begin while.
            compiler.BeginWhile();

            // We also fill dual share context.
            ShaderCompiler.Operand[] shared = new ShaderCompiler.Operand[ret.Length];
            for (int i = 0; i < ret.Length; i++)
            {
                shared[i] = ret[i];
            }

            shareContext = new DualShareContext(shared, parent.outputOperation);

            // We now go forward.
            return(ret);
        }
Beispiel #4
0
        public override ShaderCompiler.Operand[] Compile(ShaderCompiler compiler, ShaderCompiler.Operand[] operands,
                                                         FixedShaderParameters parameters, ref DualShareContext shareContext)
        {
            // We obtain input from operands and update shared context. We move all
            // operands.
            for (int i = 0; i < operands.Length; i++)
            {
                compiler.Mov(operands[i], shareContext.Operands[i]);
            }

            // We now end loop.
            compiler.EndWhile();

            // We return all values.
            return(shareContext.Operands);
        }
Beispiel #5
0
        /// <summary>
        /// Compiles using a given shader compiler.
        /// </summary>
        /// <param name="compiler">The compiler.</param>
        /// <param name="parameters">Shader parameters.</param>
        public IShader Compile(ShaderCompiler compiler, FixedShaderParameters parameters)
        {
            if (immutable == false || parameters == null || parameters.ShaderCode != this)
            {
                throw new ArgumentNullException("Argument is invalid (null) or is not part of this ShaderCode.");
            }

            lock (cacheSyncRoot)
            {
                ICacheable shader = cache.FindAndTouch(parameters);
                if (shader != null)
                {
                    return(shader as IShader);
                }
            }

            // We make validation of parameters and layouts.
            parameters.IsDefinedThrow();

            // ShaderCode must be immutable here if parameters were sucessfully created, operations must be cached.
            List <KeyValuePair <Pin, ShaderCompiler.Operand> > operands = new List <KeyValuePair <Pin, ShaderCompiler.Operand> >();

            cachedOps = (cachedOps == null) ? GraphHelper.GetSortedOperations(output) : cachedOps;

            List <DualShareContext> shareData = new List <DualShareContext>();

            // Begin compilation process.
            compiler.Begin(stage);

            // We go through all operations in right order
            for (int i = cachedOps.Count - 1; i >= 0; i--)
            {
                IOperation operation = cachedOps[i];

                // First prepare all inputs.
                Pin[] pins = operation.Inputs;
                ShaderCompiler.Operand[] inputs = new ShaderCompiler.Operand[pins.Length];
                for (uint j = 0; j < pins.Length; j++)
                {
                    // We extract it.
                    for (int z = 0; z < operands.Count; z++)
                    {
                        if (object.ReferenceEquals(operands[z].Key, pins[j]))
                        {
                            inputs[j] = operands[z].Value;
                            continue;
                        }
                    }
                }

                // Find if sharing context exists.
                int idx = shareData.FindIndex(delegate(DualShareContext c) { return(c.DestinationOperation == operation); });
                DualShareContext shareContext = null;
                if (idx >= 0)
                {
                    shareContext = shareData[idx];
                    shareData.RemoveAt(idx);
                }

                // Compile the operation.
                ShaderCompiler.Operand[] outputs = operation.Compile(compiler, inputs,
                                                                     parameters, ref shareContext);

                // We add it if it is not the same as "this" and notn-null.
                if (shareContext != null && shareContext.DestinationOperation != operation)
                {
                    shareData.Add(shareContext);
                }

                // Add all outputs.
                for (uint z = 0; z < outputs.Length; z++)
                {
                    operands.Add(new KeyValuePair <Pin, ShaderCompiler.Operand>(operation.Outputs[z], outputs[z]));
                }
            }

            // We do the compile process.
            IShader shader1 = compiler.End(parameters);

            // We add it to cache.
            lock (cacheSyncRoot)
            {
                try
                {
                    cache.Add(parameters, shader1);
                } catch (Exception)
                {
                    // This is the case when cache probably re-inserted shader.
                    IShader shader2 = cache.FindAndTouch(parameters) as IShader;
                    if (shader2 != null)
                    {
                        Common.Warning(typeof(ShaderCode), "Recompiled the same shader two times in a row.");

                        shader1.Dispose();
                        return(shader2);
                    }

                    // If not, we rethrow.
                    throw;
                }
            }

            return(shader1);
        }
 public SharpMedia.Graphics.Shaders.ShaderCompiler.Operand[] Compile(SharpMedia.Graphics.Shaders.ShaderCompiler compiler, SharpMedia.Graphics.Shaders.ShaderCompiler.Operand[] operands, SharpMedia.Graphics.Shaders.FixedShaderParameters parameters, ref DualShareContext dualOperands)
 {
     throw new Exception("The method or operation is not implemented.");
 }