static void Main() { m_FrameNumber = 0; m_Time = 0.0f; Device device; SwapChain swapChain; //var form = new RenderForm("CSharpRenderer"); var form = new CSharpRendererMainForm(); var panel = form.GetRenderingPanel(); form.ClientSize = new System.Drawing.Size(ResolutionX, ResolutionY); var description = new SwapChainDescription() { BufferCount = 2, Usage = Usage.RenderTargetOutput, OutputHandle = panel.Handle, IsWindowed = true, ModeDescription = new ModeDescription(ResolutionX, ResolutionY, new Rational(60, 1), Format.R8G8B8A8_UNorm), SampleDescription = new SampleDescription(1, 0), Flags = SwapChainFlags.AllowModeSwitch, SwapEffect = SwapEffect.Discard }; Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, description, out device, out swapChain); var swapChainResource = Resource.FromSwapChain <Texture2D>(swapChain, 0); SamplerStates.Initialize(device); ShaderManager.Initialize(device); GPUProfiler.Initialize(device); ContextHelper.Initialize(device); RenderTargetManager.Initialize(device); PostEffectHelper.Initialize(device, ResolutionX, ResolutionY); CubemapRenderHelper.Initialize(device); PerlinNoiseRenderHelper.Initialize(device, device.ImmediateContext); LightingLUTHelper.Initialize(device, device.ImmediateContext); DebugManager.Initialize(device, ResolutionX, ResolutionY); InitializeControls(form); Scene scene = new Scene(); scene.Initialize(device, form, panel, ResolutionX, ResolutionY); var resolvedRenderTarget = RenderTargetSet.CreateRenderTargetSet(device, ResolutionX, ResolutionY, Format.R8G8B8A8_UNorm, 1, false); RenderTargetSet.BindNull(device.ImmediateContext); // setting a viewport is required if you want to actually see anything var context = device.ImmediateContext; // prevent DXGI handling of alt+enter, which doesn't work properly with Winforms using (var factory = swapChain.GetParent <Factory>()) factory.SetWindowAssociation(panel.Handle, WindowAssociationFlags.IgnoreAltEnter); int counter = 0; Dictionary <string, double> profilers; profilers = new Dictionary <String, double>(); DateTime now = DateTime.Now; CustomConstantBufferInstance globalFrameConstantBuffer = ShaderManager.CreateConstantBufferInstance("GlobalFrameBuffer", device); MessagePump.Run(form, () => { TemporalSurfaceManager.UpdateTemporalSurfaces(); if (ShaderManager.UpdateShaderManager(device)) { InitializeControls(form); } GPUProfiler.BeginFrameProfiling(context); double timeDelta = (DateTime.Now - now).TotalMilliseconds; if (!form.GetFreezeTime()) { m_Time += timeDelta / 1000.0; m_FrameNumber++; } UpdateGlobalConstantBuffer(context, globalFrameConstantBuffer, form); scene.RenderFrame(context, timeDelta, resolvedRenderTarget); now = DateTime.Now; DebugManager.PresentDebug(context, resolvedRenderTarget); context.CopyResource(resolvedRenderTarget.m_RenderTargets[0].m_TextureObject2D, swapChainResource); GPUProfiler.EndFrameProfiling(context); swapChain.Present(0, PresentFlags.None); context.PixelShader.SetShaderResource(null, 0); if (GPUProfiler.m_CurrentFrameProfilerTree != null) { Action <GPUProfiler.ProfilerTreeMember, String> processLevel = null; processLevel = (GPUProfiler.ProfilerTreeMember treeMember, String level) => { string finalName = level + treeMember.m_Name; if (profilers.ContainsKey(finalName)) { profilers[finalName] += treeMember.m_Time; } else { profilers.Add(finalName, treeMember.m_Time); } foreach (var v in treeMember.m_ChildMembers) { processLevel(v, level + "_"); } }; processLevel(GPUProfiler.m_CurrentFrameProfilerTree, ""); } CheckAndUpdateDebugUI(context, form); if (++counter == 10) { UpdateControls(); DataGridView dataGridView = form.GetDataGridView(); dataGridView.Rows.Clear(); foreach (var profilerEntry in profilers) { DataGridViewRow row = new DataGridViewRow(); row.CreateCells(dataGridView); row.Cells[0].Value = profilerEntry.Key; row.Cells[1].Value = String.Format("{0}", Math.Round(profilerEntry.Value * 100.0 / 10.0) / 100.0); dataGridView.Rows.Add(row); } profilers.Clear(); counter = 0; } else { // avoid 2ms frame times... System.Threading.Thread.Sleep(10); } }); }
private static void ParseFile(Device device, string path) { List <ShaderWrapper> localShaders = new List <ShaderWrapper>(); List <Tuple <string, int, int, int> > computeRegisters = new List <Tuple <String, int, int, int> >(); using (StreamReader sr = new StreamReader(path)) { while (!sr.EndOfStream) { String line = sr.ReadLine(); Match matchShaderRegex = m_RegexWrapper.shaderRegex.Match(line); Match matchCbufferRegex = m_RegexWrapper.cbufferRegex.Match(line); Match matchSamplerRegex = m_RegexWrapper.samplerRegex.Match(line); Match matchNumThreadsRegex = m_RegexWrapper.numThreadsRegex.Match(line); Match matchGlobalDefineRegex = m_RegexWrapper.globalDefineRegex.Match(line); if (matchGlobalDefineRegex.Success) { string defineName = matchGlobalDefineRegex.Groups[1].Value; float value = Single.Parse(matchGlobalDefineRegex.Groups[2].Value, CultureInfo.InvariantCulture); if (m_GlobalDefineValues.ContainsKey(defineName)) { m_GlobalDefineValues[defineName] = value; } else { m_GlobalDefineValues.Add(defineName, value); } } if (matchCbufferRegex.Success) { Match globalBufferMatch = m_RegexWrapper.globalBufferRegex.Match(line); Match registerMatch = m_RegexWrapper.registerRegex.Match(line); if (!registerMatch.Success) { throw new Exception("Unable to find register for constant buffer"); } int cbufferRegister = Int32.Parse(registerMatch.Groups[1].Value); // We have a new cbuffer string cbufferName = matchCbufferRegex.Groups[1].Value; string cbufferText = ""; while (!sr.EndOfStream) { line = sr.ReadLine(); if (line.Contains('{')) { continue; } if (line.Contains('}')) { if (m_ConstantBuffers.ContainsKey(cbufferName)) { m_ConstantBuffers[cbufferName].ParseConstantBuffer(cbufferText, cbufferRegister, globalBufferMatch.Success); } else { CustomConstantBufferDefinition myNewConstantBuffer = new CustomConstantBufferDefinition( cbufferName, cbufferText, cbufferRegister, globalBufferMatch.Success, path); m_ConstantBuffers.Add(cbufferName, myNewConstantBuffer); } break; } cbufferText += line.Trim() + "\n"; } continue; } if (matchShaderRegex.Success) { // We have a new shader string shaderType = matchShaderRegex.Groups[1].Value; string shaderName = matchShaderRegex.Groups[2].Value; string shaderEntry = matchShaderRegex.Groups[3].Value; string shaderDefines = matchShaderRegex.Groups[4].Value; ShaderType type = ShaderType.PixelShader; switch (shaderType.ToLower()) { case "pixel": type = ShaderType.PixelShader; break; case "vertex": type = ShaderType.VertexShader; break; case "compute": type = ShaderType.ComputeShader; break; case "geometry": type = ShaderType.GeometryShader; break; } HashSet <string> defines = new HashSet <String>(); if (shaderDefines.Length > 0) { var tokens = shaderDefines.Split(new String[] { " ", "\t" }, StringSplitOptions.RemoveEmptyEntries); for (int i = 1; i < tokens.Length; ++i) { defines.Add(tokens[i]); } } ShaderWrapper newShader = new ShaderWrapper() { m_FilePath = path, m_ShaderName = shaderName, m_ShaderType = type, m_ShaderEntry = shaderEntry, m_UsedIncludes = new HashSet <String>(), m_Defines = defines }; localShaders.Add(newShader); } if (matchNumThreadsRegex.Success) { int threadsX = Int32.Parse(matchNumThreadsRegex.Groups[1].Value); int threadsY = Int32.Parse(matchNumThreadsRegex.Groups[2].Value); int threadsZ = Int32.Parse(matchNumThreadsRegex.Groups[3].Value); string nextLine = sr.ReadLine(); var tokens = nextLine.Split(new String[] { " ", "(" }, StringSplitOptions.RemoveEmptyEntries); computeRegisters.Add(new Tuple <String, int, int, int>(tokens[1], threadsX, threadsY, threadsZ)); } if (matchSamplerRegex.Success) { string samplerType = matchSamplerRegex.Groups[1].Value; string samplerName = matchSamplerRegex.Groups[2].Value; string samplerRegister = matchSamplerRegex.Groups[3].Value; m_SamplerStates[Int32.Parse(samplerRegister)] = SamplerStates.GetSamplerStateForName(samplerName); } } } foreach (var shader in localShaders) { CompileShader(shader, device); } foreach (var registers in computeRegisters) { var shaderFit = localShaders.Where (shader => shader.m_ShaderEntry == registers.Item1); foreach (var fittingShader in shaderFit) { fittingShader.m_ThreadsX = registers.Item2; fittingShader.m_ThreadsY = registers.Item3; fittingShader.m_ThreadsZ = registers.Item4; } } }
static void Main() { Device device; SwapChain swapChain; //var form = new RenderForm("CSharpRenderer"); var form = new CSharpRendererMainForm(); var panel = form.GetRenderingPanel(); form.ClientSize = new System.Drawing.Size(ResolutionX, ResolutionY); var description = new SwapChainDescription() { BufferCount = 2, Usage = Usage.RenderTargetOutput, OutputHandle = panel.Handle, IsWindowed = true, ModeDescription = new ModeDescription(ResolutionX, ResolutionY, new Rational(60, 1), Format.R8G8B8A8_UNorm), SampleDescription = new SampleDescription(1, 0), Flags = SwapChainFlags.AllowModeSwitch, SwapEffect = SwapEffect.Discard }; Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, description, out device, out swapChain); var swapChainResource = Resource.FromSwapChain <Texture2D>(swapChain, 0); SamplerStates.Initialize(device); ShaderManager.Initialize(device); GPUProfiler.Initialize(device); ContextHelper.Initialize(device); RenderTargetManager.Initialize(device); PostEffectHelper.Initialize(device, ResolutionX, ResolutionY); CubemapRenderHelper.Initialize(device); Dictionary <CustomConstantBufferDefinition.ConstantBufferPropertyField, Tuple <TrackBar, TextBox> > propertyControlBindings = new Dictionary <CustomConstantBufferDefinition.ConstantBufferPropertyField, Tuple <TrackBar, TextBox> >(); { TableLayoutPanel tableLayout = form.GetTableLayoutPanel(); var contantBuffers = ShaderManager.GetConstantBufferDefinitions(); int tableParamCounter = 1; foreach (var cb in contantBuffers) { var paramProperties = cb.GetParamProperties(); if (paramProperties.Count > 0) { Label groupLabel = new Label(); groupLabel.Text = cb.m_Name; groupLabel.BorderStyle = BorderStyle.FixedSingle; groupLabel.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom; tableLayout.Controls.Add(groupLabel, 0, tableParamCounter); tableParamCounter++; foreach (var param in paramProperties) { Label lb = new Label(); lb.Text = param.name; lb.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom; TextBox text = new TextBox(); TrackBar tb = new TrackBar(); tb.Size = new System.Drawing.Size(400, 10); tb.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom; tb.Minimum = 0; tb.Maximum = 1024; tb.Value = (int)(((Single)param.paramValue - param.paramRangeMin) / (param.paramRangeMax - param.paramRangeMin) * 1024); text.Text = ((Single)param.paramValue).ToString(); text.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom; tableLayout.Controls.Add(lb, 0, tableParamCounter); tableLayout.Controls.Add(tb, 1, tableParamCounter); tableLayout.Controls.Add(text, 2, tableParamCounter); propertyControlBindings.Add(param, new Tuple <TrackBar, TextBox>(tb, text)); tableParamCounter++; } } } } Scene scene = new Scene(); scene.Initialize(device, form, panel, ResolutionX, ResolutionY); var resolvedRenderTarget = RenderTargetSet.CreateRenderTargetSet(device, ResolutionX, ResolutionY, Format.R8G8B8A8_UNorm, 1, false); RenderTargetSet.BindNull(device.ImmediateContext); // setting a viewport is required if you want to actually see anything var context = device.ImmediateContext; // prevent DXGI handling of alt+enter, which doesn't work properly with Winforms using (var factory = swapChain.GetParent <Factory>()) factory.SetWindowAssociation(panel.Handle, WindowAssociationFlags.IgnoreAltEnter); int counter = 0; Dictionary <string, double> profilers; profilers = new Dictionary <String, double>(); MessagePump.Run(form, () => { TemporalSurfaceManager.UpdateTemporalSurfaces(); ShaderManager.UpdateShaderManager(device); GPUProfiler.BeginFrameProfiling(context); scene.RenderFrame(context, 0.0f, resolvedRenderTarget); context.CopyResource(resolvedRenderTarget.m_RenderTargets[0].m_TextureObject2D, swapChainResource); GPUProfiler.EndFrameProfiling(context); swapChain.Present(0, PresentFlags.None); context.PixelShader.SetShaderResource(null, 0); if (GPUProfiler.m_CurrentFrameProfilerTree != null) { Action <GPUProfiler.ProfilerTreeMember, String> processLevel = null; processLevel = (GPUProfiler.ProfilerTreeMember treeMember, String level) => { string finalName = level + treeMember.m_Name; if (profilers.ContainsKey(finalName)) { profilers[finalName] += treeMember.m_Time; } else { profilers.Add(finalName, treeMember.m_Time); } foreach (var v in treeMember.m_ChildMembers) { processLevel(v, level + "_"); } }; processLevel(GPUProfiler.m_CurrentFrameProfilerTree, ""); } if (++counter == 10) { foreach (var propertyBinding in propertyControlBindings) { var property = propertyBinding.Key; var trackBar = propertyBinding.Value.Item1; var textBox = propertyBinding.Value.Item2; float rawVal = (float)trackBar.Value / 1024.0f; if (property.isGamma) { rawVal = (float)Math.Pow((double)rawVal, 2.2); } float val = rawVal * (property.paramRangeMax - property.paramRangeMin) + property.paramRangeMin; property.paramValue = val; textBox.Text = val.ToString("F"); } DataGridView dataGridView = form.GetDataGridView(); dataGridView.Rows.Clear(); foreach (var profilerEntry in profilers) { DataGridViewRow row = new DataGridViewRow(); row.CreateCells(dataGridView); row.Cells[0].Value = profilerEntry.Key; row.Cells[1].Value = String.Format("{0}", Math.Round(profilerEntry.Value * 100.0 / 10.0) / 100.0); dataGridView.Rows.Add(row); } profilers.Clear(); counter = 0; } System.Threading.Thread.Sleep(15); }); }