public void DAGUsageCases2() { // We first initialize our shader. ShaderCode code = new ShaderCode(BindingStage.VertexShader); { // We write a simple Tranform code: code.InputOperation.AddInput(PinComponent.Position, PinFormat.Floatx3); Pin positon = code.InputOperation.PinAsOutput(PinComponent.Position); // We first need to expand our position to float4 (adding 1 at the end). ExpandOperation expand = new ExpandOperation(PinFormat.Floatx4, ExpandType.AddOnesAtW); expand.BindInputs(positon); Pin expPosition = expand.Outputs[0]; // We now create constant transform matrix. ConstantOperation mvpConstant = code.CreateConstant("MVP", PinFormat.Float4x4); Pin MVP = mvpConstant.Outputs[0]; // We multiply matrix and pin. MultiplyOperation mul = new MultiplyOperation(); mul.BindInputs(MVP, expPosition); Pin transPosition = mul.Outputs[0]; // We just bind transformed position to output. code.OutputOperation.AddComponentAndLink(PinComponent.Position, transPosition); } // We create constant buffer manually. ConstantBufferLayoutBuilder builder = new ConstantBufferLayoutBuilder(); builder.AppendElement("MVP", PinFormat.Float4x4, Pin.NotArray); ConstantBufferLayout layout = builder.CreateLayout(); // We now fill the data. FixedShaderParameters parameters = code.FixedParameters; parameters.AppendLayout(layout); if (!parameters.IsDefined) { throw new Exception(); } GraphicsDevice device = InitializeDevice(); // We have all parameters defined, compile the shader. VShader shader = code.Compile(device, parameters) as VShader; // Shader expects data in constant buffers. TypelessBuffer buffer = new TypelessBuffer(Usage.Default, BufferUsage.ConstantBuffer, CPUAccess.Write, GraphicsLocality.DeviceOrSystemMemory, 4 * 4 * 4); ConstantBufferView constantBuffer = buffer.CreateConstantBuffer(layout); // We fill the buffer. constantBuffer.Map(MapOptions.Write); constantBuffer.SetConstant("MVP", Math.Matrix.Matrix4x4f.Identity); constantBuffer.UnMap(); }
public unsafe GraphicsCanvas([NotNull] GraphicsDevice device, [NotNull] RenderTargetView renderTarget, Vector2f canvasUnits) { info = new GraphicsCanvasInfo(this); // Initialize shaders. Initialize(); this.unitSize = canvasUnits; this.device = device; this.renderTarget = renderTarget; this.batch = Geometry.CreateBatch(VertexData.Format, new IndexFormat(true), MaxVerticesInBatch, MaxIndicesInBatch, CyclicBufferCount); // We also immediatelly bind it to device. this.batch.BindToDevice(device); // We create vertex constants buffer. { TypelessBuffer vertexConstBuffer = new TypelessBuffer(Usage.Dynamic, BufferUsage.ConstantBuffer, CPUAccess.Write, GraphicsLocality.DeviceOrSystemMemory, 16 * 4 * 2); vertexConstBuffer.DisposeOnViewDispose = true; ConstantBufferLayoutBuilder vertexBufferLayout = new ConstantBufferLayoutBuilder(); vertexBufferLayout.AppendElement("PositionTransform", PinFormat.Float4x4); vertexBufferLayout.AppendElement("TextureTransform", PinFormat.Float4x4); vertexConstants = vertexConstBuffer.CreateConstantBuffer(vertexBufferLayout.CreateLayout()); } // We create pixel constants buffer. pixelConstants = new TypelessBuffer(Usage.Dynamic, BufferUsage.ConstantBuffer, CPUAccess.Write, GraphicsLocality.DeviceOrSystemMemory, ConstantBufferView.MaxSize); }
public unsafe void DAGUsageCases() { // We first initialize our shader. ShaderCode code = new ShaderCode(BindingStage.VertexShader); { // We write a simple Tranform code: code.InputOperation.AddInput(PinComponent.Position, PinFormat.Floatx3); Pin positon = code.InputOperation.PinAsOutput(PinComponent.Position); // We first need to expand our position to float4 (adding 1 at the end). ExpandOperation expand = new ExpandOperation(PinFormat.Floatx4, ExpandType.AddOnesAtW); expand.BindInputs(positon); Pin expPosition = expand.Outputs[0]; // We now create constant transform matrix. ConstantOperation mvpConstant = code.CreateConstant("MVP", PinFormat.Float4x4); Pin MVP = mvpConstant.Outputs[0]; // We multiply matrix and pin. MultiplyOperation mul = new MultiplyOperation(); mul.BindInputs(MVP, expPosition); Pin transPosition = mul.Outputs[0]; // We just bind transformed position to output. code.OutputOperation.AddComponentAndLink(PinComponent.Position, transPosition); } // Immutate it. code.Immutable = true; // We create constant buffer manually. ConstantBufferLayoutBuilder builder = new ConstantBufferLayoutBuilder(); builder.AppendElement("MVP", PinFormat.Float4x4, Pin.NotArray); ConstantBufferLayout layout = builder.CreateLayout(); // We now fill the data. FixedShaderParameters parameters = code.FixedParameters; parameters.AppendLayout(layout); if (!parameters.IsDefined) { throw new Exception(); } using (GraphicsDevice device = InitializeDevice()) { // We create shaders. // We have all parameters defined, compile the shader. VShader shader = code.Compile(device, parameters) as VShader; // Shader expects data in constant buffers. TypelessBuffer tbuffer = new TypelessBuffer(Usage.Dynamic, BufferUsage.ConstantBuffer, CPUAccess.Write, GraphicsLocality.DeviceOrSystemMemory, 4 * 4 * 4); ConstantBufferView constantBuffer = tbuffer.CreateConstantBuffer(layout); // We fill the buffer. constantBuffer.Map(MapOptions.Write); constantBuffer.SetConstant("MVP", new Math.Matrix.Matrix4x4f(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.5f, -0.5f, 0, 1)); constantBuffer.UnMap(); PShader pshader; VShader vshader = shader; using (ShaderCompiler compiler = device.CreateShaderCompiler()) { // And pixel shader. compiler.Begin(BindingStage.PixelShader); ShaderCompiler.Operand colour = compiler.CreateFixed(PinFormat.Floatx4, Pin.NotArray, new Vector4f(1, 0, 0, 1)); compiler.Output(colour, PinComponent.RenderTarget0); pshader = compiler.End(null) as PShader; } // We create triangles. Geometry geometry = new Geometry(); TypelessBuffer buffer = new TypelessBuffer(Usage.Static, BufferUsage.VertexBuffer, CPUAccess.None, GraphicsLocality.DeviceOrSystemMemory, 4 * 4 * 3); byte[] d = buffer.Map(MapOptions.Read); fixed(byte *p = d) { float *data = (float *)p; // Vertex 0: data[0] = -0.5f; data[1] = -0.5f; data[2] = 0.0f; data[3] = 1.0f; // Vertex 1: data[4] = 0.5f; data[5] = -0.5f; data[6] = 0.0f; data[7] = 1.0f; // Vertex 2: data[8] = 0.0f; data[9] = 0.5f; data[10] = 0.0f; data[11] = 1.0f; } buffer.UnMap(); // Create vertex buffer and view. VertexBufferView vbuffer = buffer.CreateVertexBuffer(VertexFormat.Parse("P.Fx4")); // We construct geometry. geometry[0] = vbuffer; geometry.Topology = Topology.Triangle; // Blend state. BlendState blendState = new BlendState(); blendState[0] = false; blendState = StateManager.Intern(blendState); RasterizationState rastState = new RasterizationState(); rastState.CullMode = CullMode.None; rastState.FillMode = FillMode.Solid; rastState = StateManager.Intern(rastState); DepthStencilState depthState = new DepthStencilState(); depthState.DepthTestEnabled = false; depthState.DepthWriteEnabled = false; depthState = StateManager.Intern(depthState); // Enter rendering loop. bool isClosed = false; window.Closed += delegate(Window w) { isClosed = true; }; for (uint i = 0; i < 1000; i++) { window.DoEvents(); if (!isClosed) { SwapChain chain = device.SwapChain; device.Enter(); try { // We just clear. device.Clear(chain, Colour.Black); // Set blend/rast. device.SetBlendState(blendState, Colour.White, 0xFFFFFFFF); device.RasterizationState = rastState; device.SetDepthStencilState(depthState, 0); // Sets states. device.SetVertexShader(vshader, geometry, null, null, new ConstantBufferView[] { constantBuffer }); device.SetPixelShader(pshader, null, null, null, new RenderTargetView[] { chain }, null); device.Viewport = new Region2i(0, 0, (int)chain.Width, (int)chain.Height); // Render. device.Draw(0, 3); } finally { device.Exit(); } chain.Present(); //Thread.Sleep(10); Console.WriteLine(device.DevicePerformance.CurrentFPS); } } // Dispose all. vshader.Dispose(); pshader.Dispose(); geometry.Dispose(); vbuffer.Dispose(); buffer.Dispose(); } }
unsafe void Flush(bool rebatch) { if (batch.VertexCount == 0) { if (!rebatch) { batch.EndBatch(); } return; } // We flush the buffer, first end batch. batch.EndBatch(); // We update vertex constants. vertexConstants.Map(MapOptions.Write); try { DataTransform vtransform = positionTransforms.Peek(); if (!vtransform.ProcessCPU) { vertexConstants.SetConstant("PositionTransform", Matrix4x4f.CreateTranslate(new Vector3f(-unitSize.X, -unitSize.Y, 0)) * Matrix4x4f.CreateScale(new Vector3f(2.0f, 2.0f, 2.0f)) * vtransform.Transform.RuntimeForm); } else { vertexConstants.SetConstant("PositionTransform", Matrix4x4f.Identity); } DataTransform ttransform = textureTransforms.Peek(); if (!ttransform.ProcessCPU) { vertexConstants.SetConstant("TextureTransform", ttransform.Transform.RuntimeForm); } else { vertexConstants.SetConstant("TextureTransform", Matrix4x4f.Identity); } } finally { vertexConstants.UnMap(); } // Vertex Shader: FixedShaderParameters vparams = vertexShaderCode.FixedParameters; vparams.AddLayout(0, vertexConstants.Layout); VShader vshader = vertexShaderCode.Compile(device, vparams) as VShader; // Pixel Shaders: FixedShaderParameters pparams = pixelShaderCode.FixedParameters; // We set interfaces. pparams.SetInterfaceArray("Fills", fills); // We now set per parameter data. ConstantBufferLayoutBuilder builder = new ConstantBufferLayoutBuilder(); List <TextureView> textures = new List <TextureView>(); List <SamplerState> samplers = new List <SamplerState>(); // We add per-fill data. for (int i = 0; i < fills.Count; i++) { IFill fill = fills[i]; string prefix = string.Format("Fills[{0}]", i); InterfaceHelper.ApplyInterfaceConstants(prefix, fill, builder, pparams, textures, samplers, fill.ParameterValues); } // We create view and fill data. ConstantBufferLayout layout = builder.CreateLayout(); ConstantBufferView pixelConstantsView = pixelConstants.CreateConstantBuffer(layout); pparams.AddLayout(0, layout); // TODO: this may not be needed for optimized setting. pixelConstantsView.Map(MapOptions.Write); try { for (int i = 0; i < fills.Count; i++) { IFill fill = fills[i]; string prefix = string.Format("Fills[{0}]", i); InterfaceHelper.FillInterfaceConstants(prefix, fill, pixelConstantsView, fill.ParameterValues); } } finally { pixelConstantsView.UnMap(); } // Finally compile. PShader pshader = pixelShaderCode.Compile(device, pparams) as PShader; using (DeviceLock devLock = device.Lock()) { // We now draw using data, set all states. device.SetBlendState(blendState, Colour.Black, 0xFFFFFFFF); device.SetDepthStencilState(depthStencilState, 0); device.SetRasterizationState(rasterizationState); if (viewport.Width == viewport.Height && viewport.Height == 0) { device.Viewport = new Region2i(new Vector2i(0, 0), new Vector2i((int)renderTarget.Width, (int)renderTarget.Height)); } else { device.Viewport = viewport; } // We bind stages. device.SetVertexShader(vshader, batch, null, null, new ConstantBufferView[] { vertexConstants }); device.SetPixelShader(pshader, samplers.ToArray(), textures.ToArray(), new ConstantBufferView[] { pixelConstantsView }, new RenderTargetView[] { renderTarget }, null); device.SetGeometryShader(null, null, null, null, null); // We now draw. device.DrawIndexed(0, batch.IndexCount, 0); // We clear state. device.SetVertexShader(null, null, null, null, null); device.SetPixelShader(null, null, null, null, null, null); } pixelConstantsView.Dispose(); // Fills and data is irrelavant. fills.Clear(); // We rebatch if not completelly ended. if (rebatch) { batch.BeginBatch(); } }
/// <summary> /// Composites to source. /// </summary> /// <param name="compositeOperation"></param> public void CompositeToSource(ICompositingOperation compositeOperation, BlendState blendOverwrite, Colour blendColour, Region2i viewport, RenderTargetView target) { // 1) We first prepare the providers. List <ICompositingOperation> relavantOperations = new List <ICompositingOperation>(); ListOperations(compositeOperation, relavantOperations); // 2) We extract processors. List <ICompositeInterface> processors = new List <ICompositeInterface>(relavantOperations.Count); for (int i = 0; i < relavantOperations.Count; i++) { processors.Add(relavantOperations[i].Interface); } // 3) We prepare the shader. ShaderCode pshader = PixelShader; ShaderCode vshader = VertexShader; States.BlendState bstate = blendOverwrite != null ? blendOverwrite : DefaultBlendState; States.DepthStencilState dstate = DefaultDepthStencilState; States.RasterizationState rstate = DefaultRasterizationState; FixedShaderParameters pparams = pshader.FixedParameters; FixedShaderParameters vparams = vshader.FixedParameters; ConstantBufferLayoutBuilder builder = new ConstantBufferLayoutBuilder(); List <TextureView> textures = new List <TextureView>(); List <States.SamplerState> samplers = new List <States.SamplerState>(); // We set interface array. pparams.SetInterfaceArray("Composite", processors); builder.AppendElement("Offset", PinFormat.Floatx2); // 4) We fill parameters and builder. for (int i = 0; i < processors.Count; i++) { string name = string.Format("Composite[{0}]", i); InterfaceHelper.ApplyInterfaceConstants(name, processors[i], builder, pparams, textures, samplers, processors[i].ParameterValues); } // 5) We obtain layout big enough. ConstantBufferLayout layout = builder.CreateLayout(); pparams.AddLayout(0, layout); ConstantBufferView constantBuffer = pixelTypelessConstantBuffer.CreateConstantBuffer(layout); // 6) We fill buffer. constantBuffer.Map(MapOptions.Write); try { constantBuffer.SetConstant("Offset", new Vector2f((float)viewport.X, (float)viewport.Y)); for (int i = 0; i < processors.Count; i++) { InterfaceHelper.FillInterfaceConstants(string.Format("Composite[{0}]", i), processors[i], constantBuffer, processors[i].ParameterValues); } } finally { constantBuffer.UnMap(); } // 7) We prepare geometry. // We get quad geometry Geometry geometry = alignedQuad; // ) We render the composition. GraphicsDevice device = Device; using (DeviceLock l = device.Lock()) { // We set our state objects. device.SetBlendState(bstate, blendColour, 0xFFFFFFFF); device.SetDepthStencilState(dstate, 0); device.SetRasterizationState(rstate); device.Viewport = viewport; // We prepare to render. device.SetVertexShader(vshader.Compile(device, vparams) as VShader, geometry, null, null, null); device.SetGeometryShader(null, null, null, null, null); device.SetPixelShader(pshader.Compile(device, pparams) as PShader, samplers.ToArray(), textures.ToArray(), new ConstantBufferView[] { constantBuffer }, new RenderTargetView[] { target }, null); // We render it. if (geometry.IndexBuffer != null) { device.DrawIndexed(0, 6, 0); } else { device.Draw(0, 6); } device.SetPixelShader(null, null, null, null, null, null); } // We do not use constant buffer anymore. constantBuffer.Dispose(); }
/// <summary> /// Composites to source 2. /// </summary> /// <param name="compositeOperation"></param> public void CompositeToSource2(IBinaryOperation compositeOperation, BlendState blendOverwrite, Vector2f minCoord, Vector2f maxCoord) { // 1) We first prepare the providers. List <IOperation> relavantOperations = CompositionHelper.RelavantOperations(compositeOperation); // 2) We extract processors. List <ICompositeInterface> processors = new List <ICompositeInterface>(relavantOperations.Count + 1); for (int i = 0; i < relavantOperations.Count; i++) { processors.Add(relavantOperations[i].PixelProcessor); } processors.Add(compositeOperation.PixelProcessor); // 3) We prepare the shader. ShaderCode pshader = PixelShader; ShaderCode vshader = VertexShader; States.BlendState bstate = blendOverwrite != null ? blendOverwrite : DefaultBlendState; States.DepthStencilState dstate = DefaultDepthStencilState; States.RasterizationState rstate = DefaultRasterizationState; FixedShaderParameters pparams = pshader.FixedParameters; FixedShaderParameters vparams = vshader.FixedParameters; ConstantBufferLayoutBuilder builder = new ConstantBufferLayoutBuilder(); List <TextureView> textures = new List <TextureView>(); List <States.SamplerState> samplers = new List <States.SamplerState>(); // We set interface array. pparams.SetInterfaceArray("Composite", processors); // 4) We fill parameters and builder. for (int i = 0; i < processors.Count; i++) { string name = string.Format("Composite[{0}]", i); InterfaceHelper.ApplyInterfaceConstants(name, processors[i], builder, pparams, textures, samplers, processors[i].ParameterValues); } // 5) We obtain layout big enough. ConstantBufferLayout layout = builder.CreateLayout(); pparams.AddLayout(0, layout); ConstantBufferView constantBuffer = ResourceProvider.Provide(layout.MinimumBufferSizeInBytes).CreateConstantBuffer(layout); // 6) We fill buffer. constantBuffer.Map(MapOptions.Write); try { for (int i = 0; i < processors.Count; i++) { InterfaceHelper.FillInterfaceConstants(string.Format("Composite[{i}]", i), processors[i], constantBuffer, processors[i].ParameterValues); } } finally { constantBuffer.UnMap(); } // 7) We prepare geometry. // We create quad geometry Geometry geometry = CreateQuadGeometry(minCoord, maxCoord); // ) We render the composition. GraphicsDevice device = Device; using (DeviceLock l = device.Lock()) { // We set our state objects. device.SetBlendState(bstate, Colour.White, 0xFFFFFFFF); device.SetDepthStencilState(dstate, 0); device.SetRasterizationState(rstate); // We prepare to render. device.SetVertexShader(vshader.Compile(device, vparams) as VShader, geometry, null, null, null); device.SetGeometryShader(null, null, null, null, null); device.SetPixelShader(pshader.Compile(device, pparams) as PShader, samplers.ToArray(), textures.ToArray(), new ConstantBufferView[] { constantBuffer }, new RenderTargetView[] { compositeOperation.Source2.DestinationView }, null); // We render it. if (geometry.IndexBuffer != null) { device.DrawIndexed(0, 6, 0); } else { device.Draw(0, 6); } } // We do not use constant buffer anymore. ResourceProvider.Unused(constantBuffer.TypelessResource as TypelessBuffer); }
/// <summary> /// Applies interface constants to layout. Textures and samplers are appended. /// </summary> public static void ApplyInterfaceConstants(string name, IInterface @interface, ConstantBufferLayoutBuilder builder, FixedShaderParameters pparams, List <TextureView> textures, List <States.SamplerState> samplers, params object[] parameterValues) { string prefix = name + "."; object[] parameters = parameterValues; ParameterDescription[] descs = @interface.AdditionalParameters; if (parameters.Length != descs.Length) { throw new Exception("Lengths of descriptor and parameter array incompatible."); } // We now go through all elements and append them. for (int j = 0; j < parameters.Length; j++) { ParameterDescription desc = descs[j]; object value = parameters[j]; switch (desc.Pin.Format) { case PinFormat.Integer: case PinFormat.Integerx2: case PinFormat.Integerx3: case PinFormat.Integerx4: case PinFormat.UInteger: case PinFormat.UIntegerx2: case PinFormat.UIntegerx3: case PinFormat.UIntegerx4: case PinFormat.Bool: case PinFormat.Boolx2: case PinFormat.Boolx3: case PinFormat.Boolx4: case PinFormat.SNorm: case PinFormat.SNormx2: case PinFormat.SNormx3: case PinFormat.SNormx4: case PinFormat.UNorm: case PinFormat.UNormx2: case PinFormat.UNormx3: case PinFormat.UNormx4: case PinFormat.Float: case PinFormat.Floatx2: case PinFormat.Floatx3: case PinFormat.Floatx4: case PinFormat.Float2x2: case PinFormat.Float3x3: case PinFormat.Float4x4: case PinFormat.Integer2x2: case PinFormat.Integer3x3: case PinFormat.Integer4x4: case PinFormat.UInteger2x2: case PinFormat.UInteger3x3: case PinFormat.UInteger4x4: case PinFormat.SNorm2x2: case PinFormat.SNorm3x3: case PinFormat.SNorm4x4: case PinFormat.UNorm2x2: case PinFormat.UNorm3x3: case PinFormat.UNorm4x4: builder.AppendElement(prefix + desc.Name, desc.Pin.Format); // TODO: may optimize setting data directly (map/unmap). break; case PinFormat.Texture1D: case PinFormat.Texture1DArray: case PinFormat.Texture2D: case PinFormat.Texture2DArray: case PinFormat.TextureCube: case PinFormat.Texture3D: case PinFormat.BufferTexture: pparams.SetParameter(prefix + desc.Name, (uint)textures.Count); textures.Add(value as TextureView); break; case PinFormat.Sampler: pparams.SetParameter(prefix + desc.Name, (uint)samplers.Count); samplers.Add(value as States.SamplerState); break; default: throw new NotSupportedException("Nested interfaces or some other excotic feature not supported."); } } }