コード例 #1
0
 public PhysicsDebugEffect(GraphicsDevice graphicsDevice)
     : base(graphicsDevice, bytecode ?? (bytecode = BinarySerialization.Read <EffectBytecode>(binaryBytecode)))
 {
     Color         = new Color4(1.0f);
     WorldViewProj = Matrix.Identity;
     UseUv         = true;
 }
コード例 #2
0
 private EffectProgram(GraphicsDevice device, EffectBytecode bytecode)
     : base(device)
 {
     effectBytecode = bytecode;
     Reflection     = effectBytecode.Reflection;
     CreateShaders();
 }
コード例 #3
0
        private EffectBytecode LoadEffectBytecode(DatabaseFileProvider database, ObjectId bytecodeId)
        {
            EffectBytecode bytecode = null;

            if (!bytecodes.TryGetValue(bytecodeId, out bytecode))
            {
                if (!bytecodesByPassingStorage.Contains(bytecodeId) && database.ObjectDatabase.Exists(bytecodeId))
                {
                    using (var stream = database.ObjectDatabase.OpenStream(bytecodeId))
                    {
                        bytecode = EffectBytecode.FromStream(stream);
                    }
                }
                if (bytecode != null)
                {
                    bytecodes.Add(bytecodeId, bytecode);
                }
            }

            // Always check that the bytecode is in sync with hash sources on all platforms
            if (bytecode != null && IsBytecodeObsolete(bytecode))
            {
                bytecodes.Remove(bytecodeId);
                bytecode = null;
            }

            return(bytecode);
        }
コード例 #4
0
        // Note: no need to store RTV/DSV formats

        internal PipelineState(GraphicsDevice graphicsDevice, PipelineStateDescription pipelineStateDescription) : base(graphicsDevice)
        {
            // First time, build caches
            var pipelineStateCache = GetPipelineStateCache();

            // Effect
            this.rootSignature  = pipelineStateDescription.RootSignature;
            this.effectBytecode = pipelineStateDescription.EffectBytecode;
            CreateShaders(pipelineStateCache);
            if (rootSignature != null && effectBytecode != null)
            {
                ResourceBinder.Compile(graphicsDevice, rootSignature.EffectDescriptorSetReflection, this.effectBytecode);
            }

            // TODO: Cache over Effect|RootSignature to create binding operations

            // States
            blendState = pipelineStateCache.BlendStateCache.Instantiate(pipelineStateDescription.BlendState);

            this.sampleMask   = pipelineStateDescription.SampleMask;
            rasterizerState   = pipelineStateCache.RasterizerStateCache.Instantiate(pipelineStateDescription.RasterizerState);
            depthStencilState = pipelineStateCache.DepthStencilStateCache.Instantiate(pipelineStateDescription.DepthStencilState);

            CreateInputLayout(pipelineStateDescription.InputElements);

            primitiveTopology = (SharpDX.Direct3D.PrimitiveTopology)pipelineStateDescription.PrimitiveType;
        }
コード例 #5
0
        private Effect CreateEffect(string effectName, EffectBytecode bytecode, ShaderMixinParameters usedParameters)
        {
            Effect effect;

            lock (cachedEffects)
            {
                if (!cachedEffects.TryGetValue(bytecode, out effect))
                {
                    effect = new Effect(graphicsDeviceService.GraphicsDevice, bytecode, usedParameters)
                    {
                        Name = effectName
                    };
                    cachedEffects.Add(bytecode, effect);

#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
                    foreach (var type in bytecode.HashSources.Keys)
                    {
                        // TODO: the "/path" is hardcoded, used in ImportStreamCommand and ShaderSourceManager. Find a place to share this correctly.
                        using (var pathStream = Asset.OpenAsStream(EffectCompilerBase.GetStoragePathFromShaderType(type) + "/path"))
                            using (var reader = new StreamReader(pathStream))
                            {
                                var path = reader.ReadToEnd();
                                directoryWatcher.Track(path);
                            }
                    }
#endif
                }
            }
            return(effect);
        }
コード例 #6
0
ファイル: EffectSystem.cs プロジェクト: originesia/paradox
        private Effect CreateEffect(EffectBytecode bytecode, ShaderMixinParameters usedParameters)
        {
            Effect effect;

            lock (cachedEffects)
            {
                if (!cachedEffects.TryGetValue(bytecode, out effect))
                {
                    effect      = new Effect(graphicsDeviceService.GraphicsDevice, bytecode, usedParameters);
                    effect.Name = bytecode.Name;
                    cachedEffects.Add(bytecode, effect);

#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
                    foreach (var sourcePath in bytecode.HashSources.Keys)
                    {
                        using (var pathStream = Asset.OpenAsStream(sourcePath + "/path"))
                            using (var reader = new StreamReader(pathStream))
                            {
                                var path = reader.ReadToEnd();
                                directoryWatcher.Track(path);
                            }
                    }
#endif
                }
            }
            return(effect);
        }
コード例 #7
0
ファイル: ImageEffectShader.cs プロジェクト: rohitshe/Code
        protected override void DrawCore(RenderDrawContext context)
        {
            if (EffectInstance.UpdateEffect(GraphicsDevice) || pipelineStateDirty || previousBytecode != EffectInstance.Effect.Bytecode)
            {
                // The EffectInstance might have been updated from outside
                previousBytecode = EffectInstance.Effect.Bytecode;

                pipelineState.State.SetDefaults();
                pipelineState.State.RootSignature  = EffectInstance.RootSignature;
                pipelineState.State.EffectBytecode = EffectInstance.Effect.Bytecode;
                pipelineState.State.InputElements  = PrimitiveQuad.VertexDeclaration.CreateInputElements();
                pipelineState.State.PrimitiveType  = PrimitiveQuad.PrimitiveType;
                pipelineState.State.BlendState     = blendState;
                pipelineState.State.Output.CaptureState(context.CommandList);
                pipelineState.Update();
                pipelineStateDirty = false;
            }

            context.CommandList.SetPipelineState(pipelineState.CurrentState);

            EffectInstance.Apply(context.GraphicsContext);

            // Draw a full screen quad
            context.GraphicsDevice.PrimitiveQuad.Draw(context.CommandList);
        }
コード例 #8
0
        protected override unsafe void DrawCore(RenderDrawContext context)
        {
            // Clear render targets if there is a dependency conflict (D3D11 warning)
            if (delaySetRenderTargets)
            {
                context.CommandList.ResetTargets();
            }

            if (EffectInstance.UpdateEffect(GraphicsDevice) || pipelineStateDirty || previousBytecode != EffectInstance.Effect.Bytecode)
            {
                // The EffectInstance might have been updated from outside
                previousBytecode = EffectInstance.Effect.Bytecode;

                pipelineState.State.RootSignature     = EffectInstance.RootSignature;
                pipelineState.State.EffectBytecode    = EffectInstance.Effect.Bytecode;
                pipelineState.State.BlendState        = blendState;
                pipelineState.State.DepthStencilState = depthStencilState;

                var renderTargetCount = OutputCount;
                if (renderTargetCount > 0)
                {
                    // Special case: texture cube
                    var isTextureCube = GetOutput(0).ViewDimension == TextureDimension.TextureCube;
                    if (isTextureCube)
                    {
                        renderTargetCount = 6;
                    }

                    // Capture output state manually (since render targets might not be bound if delaySetRenderTargets is set to true)
                    pipelineState.State.Output.RenderTargetCount = renderTargetCount;
                    fixed(PixelFormat *pixelFormatStart = &pipelineState.State.Output.RenderTargetFormat0)
                    for (int i = 0; i < renderTargetCount; ++i)
                    {
                        pixelFormatStart[i] = GetOutput(isTextureCube ? 0 : i).ViewFormat;
                    }
                }

                if (HasDepthStencilOutput)
                {
                    pipelineState.State.Output.DepthStencilFormat = DepthStencil.Format;
                }

                pipelineState.Update();
                pipelineStateDirty = false;
            }

            context.CommandList.SetPipelineState(pipelineState.CurrentState);

            EffectInstance.Apply(context.GraphicsContext);

            // Now that resources are bound, set render targets
            if (delaySetRenderTargets)
            {
                SetRenderTargets(context);
            }

            // Draw a full screen quad
            context.GraphicsDevice.PrimitiveQuad.Draw(context.CommandList);
        }
コード例 #9
0
 public PhysicsDebugEffect(GraphicsDevice graphicsDevice)
     : base(graphicsDevice, bytecode ?? (bytecode = EffectBytecode.FromBytesSafe(binaryBytecode)))
 {
     parameters    = new ParameterCollection();
     Color         = new Color4(1.0f);
     WorldViewProj = Matrix.Identity;
     UseUv         = true;
 }
コード例 #10
0
        internal EffectProgram(GraphicsDevice device, EffectBytecode bytecode, bool emulateDepthClamp) : base(device)
        {
            effectBytecode         = bytecode;
            this.emulateDepthClamp = emulateDepthClamp;

            // TODO OPENGL currently we modify the reflection info; need to find a better way to deal with that
            Reflection = effectBytecode.Reflection;
            CreateShaders();
        }
コード例 #11
0
 private bool IsBytecodeObsolete(EffectBytecode bytecode)
 {
     foreach (var hashSource in bytecode.HashSources)
     {
         if (GetShaderSourceHash(hashSource.Key) != hashSource.Value)
         {
             return(true);
         }
     }
     return(false);
 }
コード例 #12
0
 private bool IsBytecodeObsolete(EffectBytecode bytecode, HashSet <string> modifiedShaders)
 {
     // Don't use linq
     foreach (KeyValuePair <string, ObjectId> x in bytecode.HashSources)
     {
         if (modifiedShaders.Contains(x.Key))
         {
             return(true);
         }
     }
     return(false);
 }
コード例 #13
0
ファイル: EffectProgram.cs プロジェクト: tiomke/paradox
 public EffectProgram GetOrCreateShader(GraphicsDevice graphicsDevice, EffectBytecode bytecode)
 {
     lock (ShaderLibrary)
     {
         EffectProgram effectProgram;
         if (!ShaderLibrary.TryGetValue(bytecode, out effectProgram))
         {
             effectProgram = new EffectProgram(graphicsDevice, bytecode);
             ShaderLibrary.Add(bytecode, effectProgram);
         }
         return(effectProgram);
     }
 }
コード例 #14
0
        /// <summary>
        /// Checks if the specified bytecode is synchronized with latest source
        /// </summary>
        /// <param name="byteCode">The byte code.</param>
        /// <param name="database">The database.</param>
        /// <returns><c>true</c> if bytecode is synchronized with latest source, <c>false</c> otherwise.</returns>
        private static bool CheckBytecodeInSyncAgainstSources(EffectBytecode byteCode, DatabaseFileProvider database)
        {
            var usedSources = byteCode.HashSources;

            // Find a bytecode that is using the same hash for its pdxsl sources
            foreach (var usedSource in usedSources)
            {
                ObjectId currentId;
                if (!database.AssetIndexMap.TryGetValue(usedSource.Key, out currentId) || usedSource.Value != currentId)
                {
                    return(false);
                }
            }
            return(true);
        }
コード例 #15
0
        internal void InitializeFrom(GraphicsDevice device, EffectBytecode bytecode)
        {
            if (device == null)
            {
                throw new ArgumentNullException("device");
            }
            if (bytecode == null)
            {
                throw new ArgumentNullException("bytecode");
            }

            this.graphicsDeviceDefault = device;
            this.bytecode = bytecode;
            Initialize();
        }
コード例 #16
0
ファイル: Effect.cs プロジェクト: slagusev/paradox
        /// <summary>
        /// Initializes a new instance of the <see cref="Effect"/> class.
        /// </summary>
        /// <param name="device">The device.</param>
        /// <param name="bytecode">The bytecode.</param>
        /// <param name="usedParameters">The parameters used to create this shader (from a pdxfx).</param>
        /// <exception cref="System.ArgumentNullException">
        /// device
        /// or
        /// bytecode
        /// </exception>
        public Effect(GraphicsDevice device, EffectBytecode bytecode, ParameterCollection usedParameters = null)
        {
            if (device == null)
            {
                throw new ArgumentNullException("device");
            }
            if (bytecode == null)
            {
                throw new ArgumentNullException("bytecode");
            }

            this.graphicsDeviceDefault = device;
            this.bytecode = bytecode;
            Initialize(usedParameters);
        }
コード例 #17
0
ファイル: Effect.cs プロジェクト: yongweisun/paradox
        /// <summary>
        /// Initializes a new instance of the <see cref="Effect"/> class.
        /// </summary>
        /// <param name="device">The device.</param>
        /// <param name="bytecode">The bytecode.</param>
        /// <param name="usedParameters">The parameters used to create this shader (from a pdxfx).</param>
        /// <exception cref="System.ArgumentNullException">
        /// device
        /// or
        /// bytecode
        /// </exception>
        public Effect(GraphicsDevice device, EffectBytecode bytecode, ParameterCollection usedParameters = null)
        {
            if (device == null)
            {
                throw new ArgumentNullException("device");
            }
            if (bytecode == null)
            {
                throw new ArgumentNullException("bytecode");
            }

            parameters = new ParameterCollection();
            Initialize(device, bytecode, usedParameters);
            Changed = false;
        }
コード例 #18
0
        protected BatchBase(GraphicsDevice device, EffectBytecode defaultEffectByteCode, EffectBytecode defaultEffectByteCodeSRgb, ResourceBufferInfo resourceBufferInfo, VertexDeclaration vertexDeclaration, int indexSize = sizeof(short))
        {
            if (defaultEffectByteCode == null)
            {
                throw new ArgumentNullException(nameof(defaultEffectByteCode));
            }
            if (defaultEffectByteCodeSRgb == null)
            {
                throw new ArgumentNullException(nameof(defaultEffectByteCodeSRgb));
            }
            if (resourceBufferInfo == null)
            {
                throw new ArgumentNullException("resourceBufferInfo");
            }
            if (vertexDeclaration == null)
            {
                throw new ArgumentNullException("vertexDeclaration");
            }

            GraphicsDevice = device;
            DefaultEffect  = new Effect(device, defaultEffectByteCode)
            {
                Name = "BatchDefaultEffect"
            };
            DefaultEffectSRgb = new Effect(device, defaultEffectByteCodeSRgb)
            {
                Name = "BatchDefaultEffectSRgb"
            };

            drawsQueue   = new ElementInfo[resourceBufferInfo.BatchCapacity];
            drawTextures = new Texture[resourceBufferInfo.BatchCapacity];

            TextureComparer     = new TextureIdComparer();
            BackToFrontComparer = new SpriteBackToFrontComparer();
            FrontToBackComparer = new SpriteFrontToBackComparer();

            // set the vertex layout and size
            indexStructSize  = indexSize;
            vertexStructSize = vertexDeclaration.CalculateSize();

            parameters = new ParameterCollection();
            defaultParameterCollectionGroup = new EffectParameterCollectionGroup(device, DefaultEffect, new[] { parameters });

            // Creates the vertex buffer (shared by within a device context).
            ResourceContext = GraphicsDevice.GetOrCreateSharedData(GraphicsDeviceSharedDataType.PerContext, resourceBufferInfo.ResourceKey, d => new DeviceResourceContext(GraphicsDevice, DefaultEffect, vertexDeclaration, resourceBufferInfo, indexStructSize));
        }
コード例 #19
0
        protected BatchBase(GraphicsDevice device, EffectBytecode defaultEffectByteCode, EffectBytecode defaultEffectByteCodeSRgb, ResourceBufferInfo resourceBufferInfo, VertexDeclaration vertexDeclaration, int indexSize = sizeof(short))
        {
            if (defaultEffectByteCode == null)
            {
                throw new ArgumentNullException(nameof(defaultEffectByteCode));
            }
            if (defaultEffectByteCodeSRgb == null)
            {
                throw new ArgumentNullException(nameof(defaultEffectByteCodeSRgb));
            }
            if (resourceBufferInfo == null)
            {
                throw new ArgumentNullException("resourceBufferInfo");
            }
            if (vertexDeclaration == null)
            {
                throw new ArgumentNullException("vertexDeclaration");
            }

            graphicsDevice  = device;
            mutablePipeline = new MutablePipelineState(device);
            // TODO GRAPHICS REFACTOR Should we initialize FX lazily?
            DefaultEffect = new EffectInstance(new Effect(device, defaultEffectByteCode)
            {
                Name = "BatchDefaultEffect"
            });
            DefaultEffectSRgb = new EffectInstance(new Effect(device, defaultEffectByteCodeSRgb)
            {
                Name = "BatchDefaultEffectSRgb"
            });

            drawsQueue   = new ElementInfo[resourceBufferInfo.BatchCapacity];
            drawTextures = new Texture[resourceBufferInfo.BatchCapacity];

            TextureComparer     = new TextureIdComparer();
            BackToFrontComparer = new SpriteBackToFrontComparer();
            FrontToBackComparer = new SpriteFrontToBackComparer();

            // set the vertex layout and size
            indexStructSize  = indexSize;
            vertexStructSize = vertexDeclaration.CalculateSize();

            // Creates the vertex buffer (shared by within a device context).
            ResourceContext = graphicsDevice.GetOrCreateSharedData(GraphicsDeviceSharedDataType.PerContext, resourceBufferInfo.ResourceKey, d => new DeviceResourceContext(graphicsDevice, vertexDeclaration, resourceBufferInfo));
        }
コード例 #20
0
        private EffectProgram(GraphicsDevice device, EffectBytecode bytecode)
            : base(device)
        {
            effectBytecode = bytecode;

            // make a copy of the effect's reflection before modifying it.
            Reflection = new EffectReflection
            {
                // The members that are not modified and can be shallowly copied.
                SamplerStates = effectBytecode.Reflection.SamplerStates,
                ShaderStreamOutputDeclarations = effectBytecode.Reflection.ShaderStreamOutputDeclarations,
                StreamOutputRasterizedStream   = effectBytecode.Reflection.StreamOutputRasterizedStream,
                StreamOutputStrides            = effectBytecode.Reflection.StreamOutputStrides,

                // The members that are modified and should be deeply copied.
                ConstantBuffers  = effectBytecode.Reflection.ConstantBuffers.Select(cb => cb.Clone()).ToList(),
                ResourceBindings = new List <EffectParameterResourceData>(effectBytecode.Reflection.ResourceBindings),
            };

            CreateShaders();
        }
コード例 #21
0
        private KeyValuePair <EffectBytecode, EffectBytecodeCacheLoadSource> LoadEffectBytecode(DatabaseFileProvider database, ObjectId bytecodeId)
        {
            KeyValuePair <EffectBytecode, EffectBytecodeCacheLoadSource> bytecodePair;

            if (!bytecodes.TryGetValue(bytecodeId, out bytecodePair))
            {
                if (!bytecodesByPassingStorage.Contains(bytecodeId) && database.ObjectDatabase.Exists(bytecodeId))
                {
                    using (var stream = database.ObjectDatabase.OpenStream(bytecodeId))
                    {
                        var bytecode = EffectBytecode.FromStream(stream);

                        // Try to read an integer that would specify what kind of cache it belongs to (if undefined because of old versions, mark it as dynamic cache)
                        var cacheSource = EffectBytecodeCacheLoadSource.DynamicCache;
                        if (stream.Position < stream.Length)
                        {
                            var binaryReader = new BinarySerializationReader(stream);
                            cacheSource = (EffectBytecodeCacheLoadSource)binaryReader.ReadInt32();
                        }
                        bytecodePair = new KeyValuePair <EffectBytecode, EffectBytecodeCacheLoadSource>(bytecode, cacheSource);
                    }
                }
                if (bytecodePair.Key != null)
                {
                    bytecodes.Add(bytecodeId, bytecodePair);
                }
            }

            // Always check that the bytecode is in sync with hash sources on all platforms
            if (bytecodePair.Key != null && IsBytecodeObsolete(bytecodePair.Key))
            {
                bytecodes.Remove(bytecodeId);
                bytecodePair = new KeyValuePair <EffectBytecode, EffectBytecodeCacheLoadSource>(null, EffectBytecodeCacheLoadSource.JustCompiled);
            }

            return(bytecodePair);
        }
コード例 #22
0
ファイル: Effect.cs プロジェクト: yongweisun/paradox
        internal void Initialize(GraphicsDevice device, EffectBytecode byteCode, ParameterCollection usedParameters)
        {
            Name = byteCode.Name;
            graphicsDeviceDefault = device.RootDevice;
            program    = EffectProgram.New(graphicsDeviceDefault, byteCode);
            reflection = byteCode.Reflection;

            // prepare resource bindings used internally
            resourceBindings = new EffectParameterResourceBinding[byteCode.Reflection.ResourceBindings.Count];
            for (int i = 0; i < resourceBindings.Length; i++)
            {
                resourceBindings[i].Description = byteCode.Reflection.ResourceBindings[i];
            }
            defaultParameters = new ParameterCollection();
            inputSignature    = program.InputSignature;
            LoadDefaultParameters();

            CompilationParameters        = new ParameterCollection();
            DefaultCompilationParameters = new ParameterCollection();
            if (usedParameters != null)
            {
                foreach (var parameter in usedParameters)
                {
                    if (parameter.Key != CompilerParameters.DebugKey && parameter.Key != CompilerParameters.GraphicsPlatformKey && parameter.Key != CompilerParameters.GraphicsProfileKey)
                    {
                        CompilationParameters.SetObject(parameter.Key, parameter.Value);
                    }
                }
            }

            foreach (var key in CompilationParameters.Keys)
            {
                DefaultCompilationParameters.RegisterParameter(key, false);
            }

            Changed = true;
        }
コード例 #23
0
        protected override void DrawCore(RenderDrawContext context)
        {
            if (string.IsNullOrEmpty(ShaderSourceName))
            {
                return;
            }

            Parameters.Set(ComputeEffectShaderKeys.ThreadNumbers, ThreadNumbers);
            Parameters.Set(ComputeEffectShaderKeys.ComputeShaderName, ShaderSourceName);
            Parameters.Set(ComputeShaderBaseKeys.ThreadGroupCountGlobal, ThreadGroupCounts);

            if (EffectInstance.UpdateEffect(GraphicsDevice) || pipelineStateDirty || previousBytecode != EffectInstance.Effect.Bytecode)
            {
                // The EffectInstance might have been updated from outside
                previousBytecode = EffectInstance.Effect.Bytecode;

                pipelineState.State.SetDefaults();
                pipelineState.State.RootSignature  = EffectInstance.RootSignature;
                pipelineState.State.EffectBytecode = EffectInstance.Effect.Bytecode;
                pipelineState.Update();
                pipelineStateDirty = false;
            }

            // Apply pipeline state
            context.CommandList.SetPipelineState(pipelineState.CurrentState);

            // Apply the effect
            EffectInstance.Apply(context.GraphicsContext);

            // Draw a full screen quad
            context.CommandList.Dispatch(ThreadGroupCounts.X, ThreadGroupCounts.Y, ThreadGroupCounts.Z);

            // Un-apply
            //throw new InvalidOperationException();
            //EffectInstance.Effect.UnbindResources(GraphicsDevice);
        }
コード例 #24
0
 public EffectBytecodeCompilerResult(EffectBytecode bytecode) : this()
 {
     Bytecode = bytecode;
     CompilationLog = emptyLoggerResult;
 }
コード例 #25
0
ファイル: ResourceGroupLayout.cs プロジェクト: vvvv/stride
        public static ResourceGroupLayout New <T>(GraphicsDevice graphicsDevice, ResourceGroupDescription resourceGroupDescription, EffectBytecode effectBytecode) where T : ResourceGroupLayout, new()
        {
            var result = new T
            {
                DescriptorSetLayoutBuilder = resourceGroupDescription.DescriptorSetLayout,
                DescriptorSetLayout        = DescriptorSetLayout.New(graphicsDevice, resourceGroupDescription.DescriptorSetLayout),
                ConstantBufferReflection   = resourceGroupDescription.ConstantBufferReflection,
                Hash = resourceGroupDescription.Hash,
            };

            if (result.ConstantBufferReflection != null)
            {
                result.ConstantBufferSize = result.ConstantBufferReflection.Size;
                result.ConstantBufferHash = result.ConstantBufferReflection.Hash;
            }

            return(result);
        }
コード例 #26
0
ファイル: ResourceBinder.cs プロジェクト: vol16bit/xenko
        public void Compile(GraphicsDevice graphicsDevice, EffectDescriptorSetReflection descriptorSetLayouts, EffectBytecode effectBytecode)
        {
            descriptorSetBindings = new BindingOperation[descriptorSetLayouts.Layouts.Count][];
            for (int setIndex = 0; setIndex < descriptorSetLayouts.Layouts.Count; setIndex++)
            {
                var layout = descriptorSetLayouts.Layouts[setIndex].Layout;
                if (layout == null)
                {
                    continue;
                }

                var bindingOperations = new List <BindingOperation>();

                for (int resourceIndex = 0; resourceIndex < layout.Entries.Count; resourceIndex++)
                {
                    var layoutEntry = layout.Entries[resourceIndex];

                    // Find it in shader reflection
                    foreach (var resourceBinding in effectBytecode.Reflection.ResourceBindings)
                    {
                        if (resourceBinding.Stage == ShaderStage.None)
                        {
                            continue;
                        }

                        if (resourceBinding.KeyInfo.Key == layoutEntry.Key)
                        {
                            bindingOperations.Add(new BindingOperation
                            {
                                EntryIndex       = resourceIndex,
                                Class            = resourceBinding.Class,
                                Stage            = resourceBinding.Stage,
                                SlotStart        = resourceBinding.SlotStart,
                                ImmutableSampler = layoutEntry.ImmutableSampler,
                            });
                        }
                    }
                }

                descriptorSetBindings[setIndex] = bindingOperations.Count > 0 ? bindingOperations.ToArray() : null;
            }
        }
コード例 #27
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Effect"/> class.
 /// </summary>
 /// <param name="device">The device.</param>
 /// <param name="bytecode">The bytecode.</param>
 /// <param name="usedParameters">The parameters used to create this shader (from a sdfx).</param>
 /// <exception cref="System.ArgumentNullException">
 /// device
 /// or
 /// bytecode
 /// </exception>
 public Effect(GraphicsDevice device, EffectBytecode bytecode)
 {
     InitializeFrom(device, bytecode);
 }
コード例 #28
0
 public EffectBytecodeCompilerResult(EffectBytecode bytecode, EffectBytecodeCacheLoadSource loadSource) : this()
 {
     Bytecode = bytecode;
     CompilationLog = emptyLoggerResult;
     LoadSource = loadSource;
 }
コード例 #29
0
        public override TaskOrResult <EffectBytecodeCompilerResult> Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters)
        {
            var log = new LoggerResult();

            // Load D3D compiler dll
            // Note: No lock, it's probably fine if it gets called from multiple threads at the same time.
            if (Platform.IsWindowsDesktop && !d3dCompilerLoaded)
            {
                NativeLibrary.PreloadLibrary("d3dcompiler_47.dll");
                d3dCompilerLoaded = true;
            }

            var shaderMixinSource = mixinTree;
            var fullEffectName    = mixinTree.Name;

            // Make a copy of shaderMixinSource. Use deep clone since shaderMixinSource can be altered during compilation (e.g. macros)
            var shaderMixinSourceCopy = new ShaderMixinSource();

            shaderMixinSourceCopy.DeepCloneFrom(shaderMixinSource);
            shaderMixinSource = shaderMixinSourceCopy;

            // Generate platform-specific macros
            switch (effectParameters.Platform)
            {
            case GraphicsPlatform.Direct3D11:
                shaderMixinSource.AddMacro("SILICONSTUDIO_XENKO_GRAPHICS_API_DIRECT3D", 1);
                shaderMixinSource.AddMacro("SILICONSTUDIO_XENKO_GRAPHICS_API_DIRECT3D11", 1);
                break;

            case GraphicsPlatform.Direct3D12:
                shaderMixinSource.AddMacro("SILICONSTUDIO_XENKO_GRAPHICS_API_DIRECT3D", 1);
                shaderMixinSource.AddMacro("SILICONSTUDIO_XENKO_GRAPHICS_API_DIRECT3D12", 1);
                break;

            case GraphicsPlatform.OpenGL:
                shaderMixinSource.AddMacro("SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGL", 1);
                shaderMixinSource.AddMacro("SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLCORE", 1);
                break;

            case GraphicsPlatform.OpenGLES:
                shaderMixinSource.AddMacro("SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGL", 1);
                shaderMixinSource.AddMacro("SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES", 1);
                break;

            case GraphicsPlatform.Vulkan:
                shaderMixinSource.AddMacro("SILICONSTUDIO_XENKO_GRAPHICS_API_VULKAN", 1);
                break;

            default:
                throw new NotSupportedException();
            }

            // Generate profile-specific macros
            shaderMixinSource.AddMacro("SILICONSTUDIO_XENKO_GRAPHICS_PROFILE", (int)effectParameters.Profile);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_9_1", (int)GraphicsProfile.Level_9_1);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_9_2", (int)GraphicsProfile.Level_9_2);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_9_3", (int)GraphicsProfile.Level_9_3);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_10_0", (int)GraphicsProfile.Level_10_0);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_10_1", (int)GraphicsProfile.Level_10_1);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_11_0", (int)GraphicsProfile.Level_11_0);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_11_1", (int)GraphicsProfile.Level_11_1);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_11_2", (int)GraphicsProfile.Level_11_2);

            // In .xksl, class has been renamed to shader to avoid ambiguities with HLSL
            shaderMixinSource.AddMacro("class", "shader");

            var parsingResult = GetMixinParser().Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray());

            // Copy log from parser results to output
            CopyLogs(parsingResult, log);

            // Return directly if there are any errors
            if (parsingResult.HasErrors)
            {
                return(new EffectBytecodeCompilerResult(null, log));
            }

            // Convert the AST to HLSL
            var writer = new SiliconStudio.Shaders.Writer.Hlsl.HlslWriter
            {
                EnablePreprocessorLine = false // Allow to output links to original pdxsl via #line pragmas
            };

            writer.Visit(parsingResult.Shader);
            var shaderSourceText = writer.Text;

            if (string.IsNullOrEmpty(shaderSourceText))
            {
                log.Error($"No code generated for effect [{fullEffectName}]");
                return(new EffectBytecodeCompilerResult(null, log));
            }

            // -------------------------------------------------------
            // Save shader log
            // TODO: TEMP code to allow debugging generated shaders on Windows Desktop
#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
            var shaderId = ObjectId.FromBytes(Encoding.UTF8.GetBytes(shaderSourceText));

            var logDir = Path.Combine(Directory.GetCurrentDirectory(), "log");
            if (!Directory.Exists(logDir))
            {
                Directory.CreateDirectory(logDir);
            }
            var shaderSourceFilename = Path.Combine(logDir, "shader_" + fullEffectName.Replace('.', '_') + "_" + shaderId + ".hlsl");
            lock (WriterLock) // protect write in case the same shader is created twice
            {
                // Write shader before generating to make sure that we are having a trace before compiling it (compiler may crash...etc.)
                if (!File.Exists(shaderSourceFilename))
                {
                    File.WriteAllText(shaderSourceFilename, shaderSourceText);
                }
            }
#else
            string shaderSourceFilename = null;
#endif
            // -------------------------------------------------------

            var bytecode = new EffectBytecode {
                Reflection = parsingResult.Reflection, HashSources = parsingResult.HashSources
            };

            // Select the correct backend compiler
            IShaderCompiler compiler;
            switch (effectParameters.Platform)
            {
#if SILICONSTUDIO_PLATFORM_WINDOWS
            case GraphicsPlatform.Direct3D11:
            case GraphicsPlatform.Direct3D12:
                compiler = new Direct3D.ShaderCompiler();
                break;
#endif
            case GraphicsPlatform.OpenGL:
            case GraphicsPlatform.OpenGLES:
            case GraphicsPlatform.Vulkan:
                // get the number of render target outputs
                var rtOutputs = 0;
                var psOutput  = parsingResult.Shader.Declarations.OfType <StructType>().FirstOrDefault(x => x.Name.Text == "PS_OUTPUT");
                if (psOutput != null)
                {
                    foreach (var rto in psOutput.Fields)
                    {
                        var sem = rto.Qualifiers.OfType <Semantic>().FirstOrDefault();
                        if (sem != null)
                        {
                            // special case SV_Target
                            if (rtOutputs == 0 && sem.Name.Text == "SV_Target")
                            {
                                rtOutputs = 1;
                                break;
                            }
                            for (var i = rtOutputs; i < 8; ++i)
                            {
                                if (sem.Name.Text == ("SV_Target" + i))
                                {
                                    rtOutputs = i + 1;
                                    break;
                                }
                            }
                        }
                    }
                }
                compiler = new OpenGL.ShaderCompiler(rtOutputs);
                break;

            default:
                throw new NotSupportedException();
            }

            var shaderStageBytecodes = new List <ShaderBytecode>();

#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
            var stageStringBuilder = new StringBuilder();
#endif
            // if the shader (non-compute) does not have a pixel shader, we should add it for OpenGL and OpenGL ES.
            if ((effectParameters.Platform == GraphicsPlatform.OpenGL || effectParameters.Platform == GraphicsPlatform.OpenGLES) && !parsingResult.EntryPoints.ContainsKey(ShaderStage.Pixel) && !parsingResult.EntryPoints.ContainsKey(ShaderStage.Compute))
            {
                parsingResult.EntryPoints.Add(ShaderStage.Pixel, null);
            }

            foreach (var stageBinding in parsingResult.EntryPoints)
            {
                // Compile
                // TODO: We could compile stages in different threads to improve compiler throughput?
                var result = compiler.Compile(shaderSourceText, stageBinding.Value, stageBinding.Key, effectParameters, bytecode.Reflection, shaderSourceFilename);
                result.CopyTo(log);

                if (result.HasErrors)
                {
                    continue;
                }

                // -------------------------------------------------------
                // Append bytecode id to shader log
#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
                stageStringBuilder.AppendLine("@G    {0} => {1}".ToFormat(stageBinding.Key, result.Bytecode.Id));
                if (result.DisassembleText != null)
                {
                    stageStringBuilder.Append(result.DisassembleText);
                }
#endif
                // -------------------------------------------------------

                shaderStageBytecodes.Add(result.Bytecode);

                // When this is a compute shader, there is no need to scan other stages
                if (stageBinding.Key == ShaderStage.Compute)
                {
                    break;
                }
            }

            // Remove unused reflection data, as it is entirely resolved at compile time.
            CleanupReflection(bytecode.Reflection);
            bytecode.Stages = shaderStageBytecodes.ToArray();

#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
            lock (WriterLock) // protect write in case the same shader is created twice
            {
                var builder = new StringBuilder();
                builder.AppendLine("/**************************");
                builder.AppendLine("***** Compiler Parameters *****");
                builder.AppendLine("***************************");
                builder.Append("@P EffectName: ");
                builder.AppendLine(fullEffectName ?? "");
                builder.Append(compilerParameters?.ToStringPermutationsDetailed());
                builder.AppendLine("***************************");

                if (bytecode.Reflection.ConstantBuffers.Count > 0)
                {
                    builder.AppendLine("****  ConstantBuffers  ****");
                    builder.AppendLine("***************************");
                    foreach (var cBuffer in bytecode.Reflection.ConstantBuffers)
                    {
                        builder.AppendFormat("cbuffer {0} [Size: {1}]", cBuffer.Name, cBuffer.Size).AppendLine();
                        foreach (var parameter in cBuffer.Members)
                        {
                            builder.AppendFormat("@C    {0} => {1}", parameter.RawName, parameter.KeyInfo.KeyName).AppendLine();
                        }
                    }
                    builder.AppendLine("***************************");
                }

                if (bytecode.Reflection.ResourceBindings.Count > 0)
                {
                    builder.AppendLine("******  Resources    ******");
                    builder.AppendLine("***************************");
                    foreach (var resource in bytecode.Reflection.ResourceBindings)
                    {
                        builder.AppendFormat("@R    {0} => {1} [Stage: {2}, Slot: ({3}-{4})]", resource.RawName, resource.KeyInfo.KeyName, resource.Stage, resource.SlotStart, resource.SlotStart + resource.SlotCount - 1).AppendLine();
                    }
                    builder.AppendLine("***************************");
                }

                if (bytecode.HashSources.Count > 0)
                {
                    builder.AppendLine("*****     Sources     *****");
                    builder.AppendLine("***************************");
                    foreach (var hashSource in bytecode.HashSources)
                    {
                        builder.AppendFormat("@S    {0} => {1}", hashSource.Key, hashSource.Value).AppendLine();
                    }
                    builder.AppendLine("***************************");
                }

                if (bytecode.Stages.Length > 0)
                {
                    builder.AppendLine("*****     Stages      *****");
                    builder.AppendLine("***************************");
                    builder.Append(stageStringBuilder);
                    builder.AppendLine("***************************");
                }
                builder.AppendLine("*************************/");

                // Re-append the shader with all informations
                builder.Append(shaderSourceText);

                File.WriteAllText(shaderSourceFilename, builder.ToString());
            }
#endif

            return(new EffectBytecodeCompilerResult(bytecode, log));
        }
コード例 #30
0
ファイル: EffectCompiler.cs プロジェクト: ItayGal2/paradox
        public override TaskOrResult<EffectBytecodeCompilerResult> Compile(ShaderMixinSource mixinTree, CompilerParameters compilerParameters)
        {
            var log = new LoggerResult();

            // Load D3D compiler dll
            // Note: No lock, it's probably fine if it gets called from multiple threads at the same time.
            if (Platform.IsWindowsDesktop && !d3dCompilerLoaded)
            {
                NativeLibrary.PreloadLibrary("d3dcompiler_47.dll");
                d3dCompilerLoaded = true;
            }

            var shaderMixinSource = mixinTree;
            var fullEffectName = mixinTree.Name;
            var usedParameters = mixinTree.UsedParameters;

            // Make a copy of shaderMixinSource. Use deep clone since shaderMixinSource can be altered during compilation (e.g. macros)
            var shaderMixinSourceCopy = new ShaderMixinSource();
            shaderMixinSourceCopy.DeepCloneFrom(shaderMixinSource);
            shaderMixinSource = shaderMixinSourceCopy;

            // Generate platform-specific macros
            var platform = usedParameters.Get(CompilerParameters.GraphicsPlatformKey);
            switch (platform)
            {
                case GraphicsPlatform.Direct3D11:
                    shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_API_DIRECT3D", 1);
                    shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_API_DIRECT3D11", 1);
                    break;
                case GraphicsPlatform.OpenGL:
                    shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGL", 1);
                    shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLCORE", 1);
                    break;
                case GraphicsPlatform.OpenGLES:
                    shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGL", 1);
                    shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_API_OPENGLES", 1);
                    break;
                default:
                    throw new NotSupportedException();
            }

            // Generate profile-specific macros
            var profile = usedParameters.Get(CompilerParameters.GraphicsProfileKey);
            shaderMixinSource.AddMacro("SILICONSTUDIO_PARADOX_GRAPHICS_PROFILE", (int)profile);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_9_1", (int)GraphicsProfile.Level_9_1);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_9_2", (int)GraphicsProfile.Level_9_2);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_9_3", (int)GraphicsProfile.Level_9_3);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_10_0", (int)GraphicsProfile.Level_10_0);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_10_1", (int)GraphicsProfile.Level_10_1);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_11_0", (int)GraphicsProfile.Level_11_0);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_11_1", (int)GraphicsProfile.Level_11_1);
            shaderMixinSource.AddMacro("GRAPHICS_PROFILE_LEVEL_11_2", (int)GraphicsProfile.Level_11_2);

            var parsingResult = GetMixinParser().Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray());

            // Copy log from parser results to output
            CopyLogs(parsingResult, log);

            // Return directly if there are any errors
            if (parsingResult.HasErrors)
            {
                return new EffectBytecodeCompilerResult(null, log);
            }

            // Convert the AST to HLSL
            var writer = new SiliconStudio.Shaders.Writer.Hlsl.HlslWriter
            {
                EnablePreprocessorLine = true // Allow to output links to original pdxsl via #line pragmas
            };
            writer.Visit(parsingResult.Shader);
            var shaderSourceText = writer.Text;

            if (string.IsNullOrEmpty(shaderSourceText))
            {
                log.Error("No code generated for effect [{0}]", fullEffectName);
                return new EffectBytecodeCompilerResult(null, log);
            }

            // -------------------------------------------------------
            // Save shader log
            // TODO: TEMP code to allow debugging generated shaders on Windows Desktop
#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
            var shaderId = ObjectId.FromBytes(Encoding.UTF8.GetBytes(shaderSourceText));

            var logDir = "log";
            if (!Directory.Exists(logDir))
            {
                Directory.CreateDirectory(logDir);
            }
            var shaderSourceFilename = Path.Combine(logDir, "shader_" +  fullEffectName.Replace('.', '_') + "_" + shaderId + ".hlsl");
            lock (WriterLock) // protect write in case the same shader is created twice
            {
                // Write shader before generating to make sure that we are having a trace before compiling it (compiler may crash...etc.)
                if (!File.Exists(shaderSourceFilename))
                {
                    File.WriteAllText(shaderSourceFilename, shaderSourceText);
                }
            }
#else
            string shaderSourceFilename = null;
#endif
            // -------------------------------------------------------

            var bytecode = new EffectBytecode { Reflection = parsingResult.Reflection, HashSources = parsingResult.HashSources };

            // Select the correct backend compiler
            IShaderCompiler compiler;
            switch (platform)
            {
#if SILICONSTUDIO_PLATFORM_WINDOWS
                case GraphicsPlatform.Direct3D11:
                    compiler = new Direct3D.ShaderCompiler();
                    break;
#endif
                case GraphicsPlatform.OpenGL:
                case GraphicsPlatform.OpenGLES:
                    // get the number of render target outputs
                    var rtOutputs = 0;
                    var psOutput = parsingResult.Shader.Declarations.OfType<StructType>().FirstOrDefault(x => x.Name.Text == "PS_OUTPUT");
                    if (psOutput != null)
                    {
                        foreach (var rto in psOutput.Fields)
                        {
                            var sem = rto.Qualifiers.OfType<Semantic>().FirstOrDefault();
                            if (sem != null)
                            {
                                // special case SV_Target
                                if (rtOutputs == 0 && sem.Name.Text == "SV_Target")
                                {
                                    rtOutputs = 1;
                                    break;
                                }
                                for (var i = rtOutputs; i < 8; ++i)
                                {
                                    if (sem.Name.Text == ("SV_Target" + i))
                                    {
                                        rtOutputs = i + 1;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    compiler = new OpenGL.ShaderCompiler(rtOutputs);
                    break;
                default:
                    throw new NotSupportedException();
            }

            var shaderStageBytecodes = new List<ShaderBytecode>();

#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
            var stageStringBuilder = new StringBuilder();
#endif
            // if the shader (non-compute) does not have a pixel shader, we should add it on OpenGL ES.
            if (platform == GraphicsPlatform.OpenGLES && !parsingResult.EntryPoints.ContainsKey(ShaderStage.Pixel) && !parsingResult.EntryPoints.ContainsKey(ShaderStage.Compute))
            {
                parsingResult.EntryPoints.Add(ShaderStage.Pixel, null);
            }

            foreach (var stageBinding in parsingResult.EntryPoints)
            {
                // Compile
                // TODO: We could compile stages in different threads to improve compiler throughput?
                var result = compiler.Compile(shaderSourceText, stageBinding.Value, stageBinding.Key, usedParameters, bytecode.Reflection, shaderSourceFilename);
                result.CopyTo(log);

                if (result.HasErrors)
                {
                    continue;
                }

                // -------------------------------------------------------
                // Append bytecode id to shader log
#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
                stageStringBuilder.AppendLine("@G    {0} => {1}".ToFormat(stageBinding.Key, result.Bytecode.Id));
#endif
                // -------------------------------------------------------

                shaderStageBytecodes.Add(result.Bytecode);

                // When this is a compute shader, there is no need to scan other stages
                if (stageBinding.Key == ShaderStage.Compute)
                    break;
            }

            // In case of Direct3D, we can safely remove reflection data as it is entirely resolved at compile time.
            if (platform == GraphicsPlatform.Direct3D11)
            {
                CleanupReflection(bytecode.Reflection);
            }
            bytecode.Stages = shaderStageBytecodes.ToArray();

#if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP
            lock (WriterLock) // protect write in case the same shader is created twice
            {
                var builder = new StringBuilder();
                builder.AppendLine("/**************************");
                builder.AppendLine("***** Used Parameters *****");
                builder.AppendLine("***************************");
                builder.Append("@P EffectName: ");
                builder.AppendLine(fullEffectName ?? "");
                builder.Append(usedParameters.ToStringDetailed());
                builder.AppendLine("***************************");

                if (bytecode.Reflection.ConstantBuffers.Count > 0)
                {
                    builder.AppendLine("****  ConstantBuffers  ****");
                    builder.AppendLine("***************************");
                    foreach (var cBuffer in bytecode.Reflection.ConstantBuffers)
                    {
                        builder.AppendFormat("cbuffer {0} [Stage: {1}, Size: {2}]", cBuffer.Name, cBuffer.Stage, cBuffer.Size).AppendLine();
                        foreach (var parameter in cBuffer.Members)
                        {
                            builder.AppendFormat("@C    {0} => {1}", parameter.Param.RawName, parameter.Param.KeyName).AppendLine();
                        }
                    }
                    builder.AppendLine("***************************");
                }

                if (bytecode.Reflection.ResourceBindings.Count > 0)
                {
                    builder.AppendLine("******  Resources    ******");
                    builder.AppendLine("***************************");
                    foreach (var resource in bytecode.Reflection.ResourceBindings)
                    {
                        var parameter = resource.Param;
                        builder.AppendFormat("@R    {0} => {1} [Stage: {2}, Slot: ({3}-{4})]", parameter.RawName, parameter.KeyName, resource.Stage, resource.SlotStart, resource.SlotStart + resource.SlotCount - 1).AppendLine();
                    }
                    builder.AppendLine("***************************");
                }

                if (bytecode.HashSources.Count > 0)
                {
                    builder.AppendLine("*****     Sources     *****");
                    builder.AppendLine("***************************");
                    foreach (var hashSource in bytecode.HashSources)
                    {
                        builder.AppendFormat("@S    {0} => {1}", hashSource.Key, hashSource.Value).AppendLine();
                    }
                    builder.AppendLine("***************************");
                }

                if (bytecode.Stages.Length > 0)
                {
                    builder.AppendLine("*****     Stages      *****");
                    builder.AppendLine("***************************");
                    builder.Append(stageStringBuilder);
                    builder.AppendLine("***************************");
                }
                builder.AppendLine("*************************/");

                // Re-append the shader with all informations
                builder.Append(shaderSourceText);

                File.WriteAllText(shaderSourceFilename, builder.ToString());
            }
#endif

            return new EffectBytecodeCompilerResult(bytecode, log);
        }
コード例 #31
0
        private ViewResourceGroupLayout CreateViewResourceGroupLayout(ResourceGroupDescription resourceGroupDescription, EffectBytecode effectBytecode)
        {
            if (resourceGroupDescription.DescriptorSetLayout == null)
            {
                return(null);
            }

            // We combine both hash for DescriptorSet and cbuffer itself (if it exists)
            var hash = resourceGroupDescription.Hash;

            ViewResourceGroupLayout result;

            if (!viewResourceLayouts.TryGetValue(hash, out result))
            {
                result = new ViewResourceGroupLayout
                {
                    DescriptorSetLayout      = DescriptorSetLayout.New(RenderSystem.GraphicsDevice, resourceGroupDescription.DescriptorSetLayout),
                    ConstantBufferReflection = resourceGroupDescription.ConstantBufferReflection,
                    Entries = new ResourceGroupEntry[RenderSystem.Views.Count],
                };

                for (int index = 0; index < result.Entries.Length; index++)
                {
                    result.Entries[index].Resources = new ResourceGroup();
                }

                if (resourceGroupDescription.ConstantBufferReflection != null)
                {
                    result.ConstantBufferSize = resourceGroupDescription.ConstantBufferReflection.Size;
                    result.ConstantBufferHash = resourceGroupDescription.ConstantBufferReflection.Hash;
                }

                // Resolve slots
                result.ConstantBufferOffsets = new int[viewCBufferOffsetSlots.Count];
                for (int index = 0; index < viewCBufferOffsetSlots.Count; index++)
                {
                    ResolveCBufferOffset(result, index, viewCBufferOffsetSlots[index].Variable);
                }

                viewResourceLayouts.Add(hash, result);
            }

            return(result);
        }
コード例 #32
0
 public EffectBytecodeCompilerResult(EffectBytecode bytecode, LoggerResult compilationLog)
 {
     Bytecode = bytecode;
     CompilationLog = compilationLog;
     LoadSource = EffectBytecodeCacheLoadSource.JustCompiled;
 }
コード例 #33
0
 public EffectBytecodeCompilerResult(EffectBytecode bytecode, LoggerResult compilationLog)
 {
     Bytecode = bytecode;
     CompilationLog = compilationLog;
 }
コード例 #34
0
ファイル: ResourceGroupLayout.cs プロジェクト: vvvv/stride
 public static ResourceGroupLayout New(GraphicsDevice graphicsDevice, ResourceGroupDescription resourceGroupDescription, EffectBytecode effectBytecode)
 {
     return(New <ResourceGroupLayout>(graphicsDevice, resourceGroupDescription, effectBytecode));
 }
コード例 #35
0
ファイル: EffectCompilerCache.cs プロジェクト: cg123/xenko
 private bool IsBytecodeObsolete(EffectBytecode bytecode, HashSet<string> modifiedShaders)
 {
     // Don't use linq
     foreach (KeyValuePair<string, ObjectId> x in bytecode.HashSources)
     {
         if (modifiedShaders.Contains(x.Key)) return true;
     }
     return false;
 }
コード例 #36
0
        public static EffectDescriptorSetReflection New(GraphicsDevice graphicsDevice, EffectBytecode effectBytecode, List <string> effectDescriptorSetSlots, string defaultSetSlot)
        {
            // Find resource groups
            // TODO: We should precompute most of that at compile time in BytecodeReflection
            // just waiting for format to be more stable
            var descriptorSetLayouts = new EffectDescriptorSetReflection {
                DefaultSetSlot = defaultSetSlot
            };

            foreach (var effectDescriptorSetSlot in effectDescriptorSetSlots)
            {
                // Find all resources related to this slot name
                // NOTE: Ordering is mirrored by GLSL layout in Vulkan
                var  descriptorSetLayoutBuilder = new DescriptorSetLayoutBuilder();
                bool hasBindings = false;
                foreach (var resourceBinding in effectBytecode.Reflection.ResourceBindings
                         .Where(x => x.ResourceGroup == effectDescriptorSetSlot || (effectDescriptorSetSlot == defaultSetSlot && (x.ResourceGroup == null || x.ResourceGroup == "Globals")))
                         .GroupBy(x => new { Key = x.KeyInfo.Key, Class = x.Class, Type = x.Type, ElementType = x.ElementType.Type, SlotCount = x.SlotCount, LogicalGroup = x.LogicalGroup })
                         .OrderBy(x => x.Key.Class == EffectParameterClass.ConstantBuffer ? 0 : 1)) // Note: Putting cbuffer first for now
                {
                    SamplerState samplerState = null;
                    if (resourceBinding.Key.Class == EffectParameterClass.Sampler)
                    {
                        var matchingSamplerState = effectBytecode.Reflection.SamplerStates.FirstOrDefault(x => x.Key == resourceBinding.Key.Key);
                        if (matchingSamplerState != null)
                        {
                            samplerState = SamplerState.New(graphicsDevice, matchingSamplerState.Description);
                        }
                    }
                    hasBindings = true;

                    descriptorSetLayoutBuilder.AddBinding(resourceBinding.Key.Key, resourceBinding.Key.LogicalGroup, resourceBinding.Key.Class, resourceBinding.Key.Type, resourceBinding.Key.ElementType, resourceBinding.Key.SlotCount, samplerState);
                }

                descriptorSetLayouts.AddLayout(effectDescriptorSetSlot, hasBindings ? descriptorSetLayoutBuilder : null);
            }

            return(descriptorSetLayouts);
        }
コード例 #37
0
ファイル: EffectCompilerCache.cs プロジェクト: cg123/xenko
 private bool IsBytecodeObsolete(EffectBytecode bytecode)
 {
     foreach (var hashSource in bytecode.HashSources)
     {
         if (GetShaderSourceHash(hashSource.Key) != hashSource.Value)
         {
             return true;
         }
     }
     return false;
 }