public void Compile(GraphicsDevice graphicsDevice, EffectDescriptorSetReflection descriptorSetLayouts, EffectBytecode effectBytecode) { resourceGroupBindings = new ResourceGroupBinding[descriptorSetLayouts.Layouts.Count]; for (int setIndex = 0; setIndex < descriptorSetLayouts.Layouts.Count; setIndex++) { var layout = descriptorSetLayouts.Layouts[setIndex].Layout; if (layout == null) { resourceGroupBindings[setIndex] = new ResourceGroupBinding { ConstantBufferSlot = -1 }; continue; } var resourceGroupBinding = new ResourceGroupBinding(); for (int resourceIndex = 0; resourceIndex < layout.Entries.Count; resourceIndex++) { var layoutEntry = layout.Entries[resourceIndex]; if (layoutEntry.Class == EffectParameterClass.ConstantBuffer) { var constantBuffer = effectBytecode.Reflection.ConstantBuffers.First(x => x.Name == layoutEntry.Key.Name); resourceGroupBinding.ConstantBufferSlot = resourceIndex; resourceGroupBinding.ConstantBufferPreallocated = Buffer.Constant.New(graphicsDevice, constantBuffer.Size); } } resourceGroupBindings[setIndex] = resourceGroupBinding; } }
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, 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.SlotCount, samplerState); } descriptorSetLayouts.AddLayout(effectDescriptorSetSlot, hasBindings ? descriptorSetLayoutBuilder : null); } return descriptorSetLayouts; }
private EffectProgram(GraphicsDevice device, EffectBytecode bytecode) : base(device) { effectBytecode = bytecode; Reflection = effectBytecode.Reflection; CreateShaders(); }
public PhysicsDebugEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, bytecode ?? (bytecode = EffectBytecode.FromBytesSafe(binaryBytecode))) { parameters = new ParameterCollection(); Color = new Color4(1.0f); WorldViewProj = Matrix.Identity; UseUv = true; }
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; } }
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(); }
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; } }
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(); }
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.RootSignature = EffectInstance.RootSignature; pipelineState.State.EffectBytecode = EffectInstance.Effect.Bytecode; 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); }
public static void Write(string name, CompilerParameters parameters, EffectBytecode effectData, TextWriter writer) { const string codeTemplate = @"//------------------------------------------------------------------------------ // <auto-generated> // Xenko Effect Compiler File Generated: {0}// // Command Line: {7} // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ namespace {1} {{ {2} class {3} {{ {4} static readonly byte[] {5} = new byte[] {{ {6} }}; }} }} "; var effectToGenerateText = new StringBuilder(); effectToGenerateText.AppendFormat("// Effect [{0}]\r\n", name); var buffer = new MemoryStream(); effectData.WriteTo(buffer); var bufferAsText = new StringBuilder(); var bufferArray = buffer.ToArray(); for (int i = 0; i < bufferArray.Length; i++) { bufferAsText.Append(bufferArray[i]).Append(", "); if (i > 0 && (i % 64) == 0) { bufferAsText.AppendLine(); } } var classDeclaration = parameters.Get(EffectSourceCodeKeys.ClassDeclaration); var fieldDeclaration = parameters.Get(EffectSourceCodeKeys.FieldDeclaration); var nameSpace = parameters.Get(EffectSourceCodeKeys.Namespace); var className = parameters.Get(EffectSourceCodeKeys.ClassName) ?? name; var fieldName = parameters.Get(EffectSourceCodeKeys.FieldName); var commandLine = string.Join(" ", Environment.GetCommandLineArgs()); var graphicsPlatform = parameters.EffectParameters.Platform; string xenkoDefine = "undefined"; switch (graphicsPlatform) { case GraphicsPlatform.Direct3D11: case GraphicsPlatform.Direct3D12: xenkoDefine = "SILICONSTUDIO_XENKO_GRAPHICS_API_DIRECT3D"; break; case GraphicsPlatform.OpenGL: xenkoDefine = "SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLCORE"; break; case GraphicsPlatform.OpenGLES: xenkoDefine = "SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES"; break; case GraphicsPlatform.Vulkan: xenkoDefine = "SILICONSTUDIO_XENKO_GRAPHICS_API_VULKAN"; break; } writer.WriteLine("#if {0}", xenkoDefine); writer.Write(codeTemplate, effectToGenerateText, // {0} nameSpace, // {1} classDeclaration, // {2} className, // {3} fieldDeclaration, // {4} fieldName, // {5} bufferAsText, // {6} commandLine); // {7} writer.WriteLine("#endif"); writer.Flush(); }
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); }
public static EffectProgram New(GraphicsDevice graphicsDevice, EffectBytecode bytecode) { var effectProgramLibrary = graphicsDevice.GetOrCreateSharedData(GraphicsDeviceSharedDataType.PerDevice, typeof(EffectProgram), d => new EffectProgramLibrary()); return effectProgramLibrary.GetOrCreateShader(graphicsDevice, bytecode); }