private void InitializeDrawComponent() { mDrawBeziersVertexShader = new GpuVertexShader(mDevice, GpuVertexShader.Compile(Properties.Resources.DrawBeziersShader, "vs_main")); mDrawBezierVertexShader = new GpuVertexShader(mDevice, GpuVertexShader.Compile(Properties.Resources.DrawBezierShader, "vs_main")); mDrawBeziersPixelShader = new GpuPixelShader(mDevice, GpuPixelShader.Compile(Properties.Resources.DrawBeziersShader, "ps_main")); mDrawBezierPixelShader = new GpuPixelShader(mDevice, GpuPixelShader.Compile(Properties.Resources.DrawBezierShader, "ps_main")); mEquationBuffer = new GpuBuffer( Utility.SizeOf <Equation>(), Utility.SizeOf <Equation>(), mDevice, GpuResourceInfo.ConstantBuffer()); mDrawVertexBuffer = new GpuBuffer( Utility.SizeOf <Vertex>() * 4, Utility.SizeOf <Vertex>(), mDevice, GpuResourceInfo.VertexBuffer()); mDrawIndexBuffer = new GpuBuffer( Utility.SizeOf <uint>() * 6, Utility.SizeOf <uint>(), mDevice, GpuResourceInfo.IndexBuffer()); var indices = new uint[] { 0, 1, 2, 0, 2, 3 }; mDrawIndexBuffer.Update(indices); }
private T Reduce <T>(UploadBuffer data, ReduceShader shader) where T : struct { Console.WriteLine("num groups: " + Utility.DivideRoundUp(data.ByteSize / 4, ReduceShader.ElementsPerGroup)); using (var buf = new GpuBuffer(4, data.ByteSize / 4)) { buf.CopyFrom(data); using (var timer = new GpuTimer()) { timer.Start(); //for(int i = 0; i < 100; ++i) shader.Run(buf, data.ByteSize / 4); timer.Stop(); Console.WriteLine(timer.GetDelta()); } using (var res = new DownloadBuffer(4)) { res.CopyFrom(buf, Marshal.SizeOf <T>()); var resData = res.GetData <T>(); return(resData); } } }
/// <summary> /// performs a reduce on the buffer. The final value will be at buffer[0] /// </summary> /// <param name="numElements">number of elements for the reduce</param> public void Run(GpuBuffer buffer, int numElements) { Device.Get().Compute.Set(shader.Compute); Device.Get().Compute.SetUnorderedAccessView(0, buffer.View); while (numElements > 1) { int numGroups = Utility.Utility.DivideRoundUp(numElements, ElementsPerGroup); numBuffer.SetData(numElements); Device.Get().Compute.SetConstantBuffer(0, numBuffer.Handle); // test if numGroups > DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION var numSplits = Utility.Utility.DivideRoundUp(numGroups, Device.DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION); if (numSplits > 1) { Device.Get().Dispatch(Device.DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION, numSplits); } else { Device.Get().Dispatch(numGroups, 1); } numElements = numGroups; } Device.Get().Compute.Set(null); }
private void InitializeRectangleBuffer() { //init rectangle index data uint[] rectangleIndices = new uint[] { 0, 4, 1, 1, 4, 5, 0, 3, 4, 3, 7, 4, 3, 6, 7, 2, 6, 3, 2, 1, 6, 1, 5, 6 }; //init rectangle vertex and index buffer mRectangleVertexBuffer = new GpuBuffer( Utility.SizeOf <GuiVertex>() * 8, Utility.SizeOf <GuiVertex>() * 1, mDevice, GpuResourceInfo.VertexBuffer()); mRectangleIndexBuffer = new GpuBuffer( Utility.SizeOf <uint>() * 24, Utility.SizeOf <uint>() * 1, mDevice, GpuResourceInfo.IndexBuffer()); mRectangleIndexBuffer.Update(rectangleIndices); }
//public bool HasAlpha => !(Min.Alpha == 1.0f && Max.Alpha == 1.0f); internal float GetStats(ITexture texture, int layer, int mipmap, StatisticsShader statShader, ReduceShader redShader, bool normalize) { // obtain a buffer that is big enough int numElements = texture.Size.GetMip(mipmap).Product; if (layer == -1) { numElements *= texture.NumLayers; } if (buffer == null || buffer.ElementCount < numElements) { buffer?.Dispose(); buffer = new GpuBuffer(4, numElements); } // copy all values into buffer statShader.CopyToBuffer(texture, buffer, layer, mipmap); // execute reduce redShader.Run(buffer, numElements); shared.Download.CopyFrom(buffer); var res = shared.Download.GetData <float>(); if (normalize) { res /= numElements; } return(res); }
public override Status StartRun(Texture texture) { Debug.Log("This graph is for testing official examples. You can customize the graph by editing `official_demo_android.txt` (default is `hand_tracking_mobile.pbtxt`)"); sidePacket = new SidePacket(); sidePacket.Emplace("num_hands", new IntPacket(2)); #if UNITY_ANDROID var glTextureName = texture.GetNativeTexturePtr(); var textureWidth = texture.width; var textureHeight = texture.height; GpuBuffer gpuBuffer = null; gpuHelper.RunInGlContext(() => { var glContext = GlContext.GetCurrent(); var glTextureBuffer = new GlTextureBuffer((UInt32)glTextureName, textureWidth, textureHeight, GpuBufferFormat.kBGRA32, OnReleaseDestinationTexture, glContext); gpuBuffer = new GpuBuffer(glTextureBuffer); return(Status.Ok()); }).AssertOk(); outputPacket = new GpuBufferPacket(gpuBuffer); sidePacket.Emplace(destinationBufferName, outputPacket); #endif return(graph.StartRun(sidePacket)); }
public PixelValueShader(SharedModel shared) { shader2D = new DirectX.Shader(DirectX.Shader.Type.Compute, GetSource(ShaderBuilder.Builder2D), "PixelValueShader"); shader3D = new DirectX.Shader(DirectX.Shader.Type.Compute, GetSource(ShaderBuilder.Builder3D), "PixelValueShader"); readBuffer = shared.Download; cbuffer = shared.Upload; dstBuffer = new GpuBuffer(4 * 4, 1); }
/// <summary> /// allocates a buffer that is big enough to hold numElement floats /// </summary> /// <param name="numElements"></param> /// <returns></returns> internal GpuBuffer GetBuffer(int numElements) { if (buffer == null || buffer.ElementCount < numElements) { buffer?.Dispose(); buffer = new GpuBuffer(4, numElements); } return(buffer); }
/// <summary> /// puts statistic data of all pixels into the buffer /// </summary> /// <param name="lm">range with single mipmap</param> /// <param name="offset">offset in each direction</param> /// <param name="source"></param> /// <param name="buffer"></param> internal void CopyToBuffer(ITexture source, GpuBuffer buffer, LayerMipmapRange lm, Size3 offset) { Debug.Assert(lm.IsSingleMipmap); // copy pixels from the source image into a texture from the texture cache var dev = Device.Get(); if (source.Is3D) { dev.Compute.Set(shader3d.Compute); } else { dev.Compute.Set(shader.Compute); } var dim = source.Size.GetMip(lm.Mipmap); AdjustDim(ref dim, ref offset, source.Is3D); var numLayers = source.LayerMipmap.Layers; var curData = new BufferData { Level = lm.Mipmap, TrueBool = true, Offset = offset, Size = dim }; if (lm.AllLayer) { dev.Compute.SetShaderResource(0, source.View); } else { // single layer dev.Compute.SetShaderResource(0, source.GetSrView(lm.Single)); curData.Level = 0; // view with single level numLayers = 1; } cbuffer.SetData(curData); // buffer big enough? Debug.Assert(buffer.ElementCount >= dim.Product * numLayers); dev.Compute.SetUnorderedAccessView(0, buffer.View); dev.Compute.SetConstantBuffer(0, cbuffer.Handle); dev.Dispatch(Utility.Utility.DivideRoundUp(dim.Width, LocalSizeX), Utility.Utility.DivideRoundUp(dim.Height, LocalSizeY), Math.Max(dim.Depth, numLayers)); dev.Compute.SetUnorderedAccessView(0, null); dev.Compute.SetShaderResource(0, null); }
public void DrawScreen(GpuBuffer gpuBuffer) { if (!isWebCamReady) { return; } #if UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || UNITY_ANDROID // TODO: create an external texture outputTexture.UpdateExternalTexture((IntPtr)gpuBuffer.GetGlTextureBuffer().Name()); #else throw new NotSupportedException(); #endif }
static IntPtr PushInputInGlContext() { try { var glContext = GlContext.GetCurrent(); var glTextureBuffer = new GlTextureBuffer((UInt32)currentTextureName, currentTextureFrame.width, currentTextureFrame.height, currentTextureFrame.gpuBufferformat, currentTextureFrame.OnRelease, glContext); var gpuBuffer = new GpuBuffer(glTextureBuffer); // TODO: ensure the returned status won't be garbage collected prematurely. return(graph.AddPacketToInputStream(inputStream, new GpuBufferPacket(gpuBuffer, currentTimestamp)).mpPtr); } catch (Exception e) { return(Status.FailedPrecondition(e.ToString()).mpPtr); } }
private void InitializeConstantBuffer() { //init shader buffer mTransformBuffer = new GpuBuffer( Utility.SizeOf <GuiTransform>(), Utility.SizeOf <GuiTransform>(), mDevice, GpuResourceInfo.ConstantBuffer()); mRenderConfigBuffer = new GpuBuffer( Utility.SizeOf <GuiRenderConfig>(), Utility.SizeOf <GuiRenderConfig>(), mDevice, GpuResourceInfo.ConstantBuffer()); }
/// <summary> /// puts statistic data of all pixels into the buffer /// </summary> internal void CopyToBuffer(ITexture source, GpuBuffer buffer, int layer = -1, int mipmap = 0) { // copy pixels from the source image into a texture from the texture cache var dev = Device.Get(); if (source.Is3D) { dev.Compute.Set(shader3d.Compute); } else { dev.Compute.Set(shader.Compute); } var dim = source.Size.GetMip(mipmap); var numLayers = source.NumLayers; var curData = new StatisticsData { Level = mipmap, TrueBool = true }; if (layer == -1) { dev.Compute.SetShaderResource(0, source.View); } else { // single layer dev.Compute.SetShaderResource(0, source.GetSrView(layer, mipmap)); curData.Level = 0; // view with single level numLayers = 1; } cbuffer.SetData(curData); // buffer big enough? Debug.Assert(buffer.ElementCount >= dim.Product * numLayers); dev.Compute.SetUnorderedAccessView(0, buffer.View); dev.Compute.SetConstantBuffer(0, cbuffer.Handle); dev.Dispatch(Utility.Utility.DivideRoundUp(dim.Width, LocalSizeX), Utility.Utility.DivideRoundUp(dim.Height, LocalSizeY), Math.Max(dim.Depth, numLayers)); dev.Compute.SetUnorderedAccessView(0, null); dev.Compute.SetShaderResource(0, null); }
public BezierRender(GpuDevice device) { //bezier render is a simple render for rendering quadratic bezier curve mDevice = device; //default transform is I Transform = Matrix4x4.Identity; //init blend state mBlendState = new GpuBlendState(mDevice, new RenderTargetBlendDescription() { AlphaBlendOperation = GpuBlendOperation.Add, BlendOperation = GpuBlendOperation.Add, DestinationAlphaBlend = GpuBlendOption.InverseSourceAlpha, DestinationBlend = GpuBlendOption.InverseSourceAlpha, SourceAlphaBlend = GpuBlendOption.SourceAlpha, SourceBlend = GpuBlendOption.SourceAlpha, IsBlendEnable = true }); //init rasterizer state mRasterizerState = new GpuRasterizerState(mDevice, GpuFillMode.Solid, GpuCullMode.None); //initalize render component InitializeFillComponent(); InitializeDrawComponent(); //init input layout //Position : float3 //Texcoord : float2 //Color : float4 mInputLayout = new GpuInputLayout(mDevice, new InputElement[] { new InputElement("POSITION", 0, 12), new InputElement("TEXCOORD", 0, 8), new InputElement("COLOR", 0, 16) }, mFillBezierVertexShader); //init constant buffer mTransformBuffer = new GpuBuffer( Utility.SizeOf <TransformMatrix>(), Utility.SizeOf <TransformMatrix>(), mDevice, GpuResourceInfo.ConstantBuffer()); MSAAStatus = true; }
/// <summary> /// performs a reduce on the buffer. The final value will be at buffer[0] /// </summary> /// <param name="numElements">number of elements for the reduce</param> public void Run(GpuBuffer buffer, int numElements) { Device.Get().Compute.Set(shader.Compute); Device.Get().Compute.SetUnorderedAccessView(0, buffer.View); while (numElements > 1) { int numGroups = Utility.Utility.DivideRoundUp(numElements, ElementsPerGroup); numBuffer.SetData(numElements); Device.Get().Compute.SetConstantBuffer(0, numBuffer.Handle); Device.Get().Dispatch(numGroups, 1); numElements = numGroups; } Device.Get().Compute.Set(null); }
private void InitializeSquareBuffer() { //init render object vertex buffer and index buffer //init square vertex data GuiVertex[] squareVertices = new GuiVertex[] { new GuiVertex() { Position = new Vector3f(0, 0, 0), Texcoord = new Vector2f(0, 0) }, new GuiVertex() { Position = new Vector3f(0, 1, 0), Texcoord = new Vector2f(0, 1) }, new GuiVertex() { Position = new Vector3f(1, 1, 0), Texcoord = new Vector2f(1, 1) }, new GuiVertex() { Position = new Vector3f(1, 0, 0), Texcoord = new Vector2f(1, 0) } }; //init square index data uint[] squareIndices = new uint[] { 0, 1, 2, 0, 2, 3 }; //init square buffer and update mSquareVertexBuffer = new GpuBuffer( Utility.SizeOf <GuiVertex>() * squareVertices.Length, Utility.SizeOf <GuiVertex>() * 1, mDevice, GpuResourceInfo.VertexBuffer()); mSquareIndexBuffer = new GpuBuffer( Utility.SizeOf <uint>() * squareIndices.Length, Utility.SizeOf <uint>() * 1, mDevice, GpuResourceInfo.IndexBuffer()); mSquareVertexBuffer.Update(squareVertices); mSquareIndexBuffer.Update(squareIndices); }
/// <summary> /// Convert <paramref name="colors" /> to a packet and send it to the input stream. /// </summary> public Status PushInput(TextureFrame textureFrame) { var timestamp = new Timestamp(System.Environment.TickCount & System.Int32.MaxValue); ImageFrame imageFrame = null; if (!IsGpuEnabled()) { imageFrame = new ImageFrame( ImageFormat.Format.SRGBA, textureFrame.width, textureFrame.height, 4 * textureFrame.width, textureFrame.GetRawNativeByteArray()); textureFrame.Release(); var packet = new ImageFramePacket(imageFrame, timestamp); return(graph.AddPacketToInputStream(inputStream, packet)); } #if UNITY_ANDROID var glTextureName = textureFrame.GetNativeTexturePtr(); return(gpuHelper.RunInGlContext(() => { var glContext = GlContext.GetCurrent(); var glTextureBuffer = new GlTextureBuffer((UInt32)glTextureName, textureFrame.width, textureFrame.height, textureFrame.gpuBufferformat, textureFrame.OnRelease, glContext); var gpuBuffer = new GpuBuffer(glTextureBuffer); return graph.AddPacketToInputStream(inputStream, new GpuBufferPacket(gpuBuffer, timestamp)); })); #else imageFrame = new ImageFrame( ImageFormat.Format.SRGBA, textureFrame.width, textureFrame.height, 4 * textureFrame.width, textureFrame.GetRawNativeByteArray()); textureFrame.Release(); return(gpuHelper.RunInGlContext(() => { var texture = gpuHelper.CreateSourceTexture(imageFrame); var gpuBuffer = texture.GetGpuBufferFrame(); Gl.Flush(); texture.Release(); return graph.AddPacketToInputStream(inputStream, new GpuBufferPacket(gpuBuffer, timestamp)); })); #endif }
private void InitializeFillComponent() { //compile vertex and pixel shader to render bezier curve mFillBeziersVertexShader = new GpuVertexShader(mDevice, GpuVertexShader.Compile(Properties.Resources.FillBeziersShader, "vs_main")); mFillBezierVertexShader = new GpuVertexShader(mDevice, GpuVertexShader.Compile(Properties.Resources.FillBezierShader, "vs_main")); mFillBeziersPixelShader = new GpuPixelShader(mDevice, GpuPixelShader.Compile(Properties.Resources.FillBeziersShader, "ps_main")); mFillBezierPixelShader = new GpuPixelShader(mDevice, GpuPixelShader.Compile(Properties.Resources.FillBezierShader, "ps_main")); //init vertex and index buffer //vertex data will be made when we draw bezier curve mFillVertexBuffer = new GpuBuffer( Utility.SizeOf <Vertex>() * 3, Utility.SizeOf <Vertex>() * 1, mDevice, GpuResourceInfo.VertexBuffer()); mFillIndexBuffer = new GpuBuffer( Utility.SizeOf <uint>() * 3, Utility.SizeOf <uint>() * 1, mDevice, GpuResourceInfo.IndexBuffer()); uint[] indices = new uint[] { 0, 1, 2 }; mFillIndexBuffer.Update(indices); mTrianglePointsBuffer = new GpuBuffer( Utility.SizeOf <TrianglePoints>(), Utility.SizeOf <TrianglePoints>(), mDevice, GpuResourceInfo.ConstantBuffer()); mTriangleColorsBuffer = new GpuBuffer( Utility.SizeOf <TriangleColors>(), Utility.SizeOf <TriangleColors>(), mDevice, GpuResourceInfo.ConstantBuffer()); }
public GuiRender(GpuDevice device) { //gui render is a simple render to render gui object //gui render can provide some simple object draw function //we can replace it to our render and we can use it in the gui system render function mDevice = device; //default transform is I Transform = Matrix4x4.Identity; //init blend state mBlendState = new GpuBlendState(mDevice, new RenderTargetBlendDescription() { AlphaBlendOperation = GpuBlendOperation.Add, BlendOperation = GpuBlendOperation.Add, DestinationAlphaBlend = GpuBlendOption.InverseSourceAlpha, DestinationBlend = GpuBlendOption.InverseSourceAlpha, SourceAlphaBlend = GpuBlendOption.SourceAlpha, SourceBlend = GpuBlendOption.SourceAlpha, IsBlendEnable = true }); //init vertex shader, for all draw command we use same vertex shader mVertexShader = new GpuVertexShader(mDevice, GpuVertexShader.Compile(Properties.Resources.GuiRenderCommonVertexShader)); //init pixel shader, we will choose the best pixel shader for different draw command mColorPixelShader = new GpuPixelShader(mDevice, GpuPixelShader.Compile(Properties.Resources.GuiRenderColorPixelShader)); mTexturePixelShader = new GpuPixelShader(mDevice, GpuPixelShader.Compile(Properties.Resources.GuiRenderTexturePixelShader)); //init sampler state mSamplerState = new GpuSamplerState(mDevice); //init input layout //Position : float3 //Texcoord : float2 mInputLayout = new GpuInputLayout(mDevice, new InputElement[] { new InputElement("POSITION", 0, 12), new InputElement("TEXCOORD", 0, 8) }, mVertexShader); //init render object vertex buffer and index buffer //init square vertex data Vertex[] squareVertices = new Vertex[] { new Vertex() { Position = new Vector3(0, 0, 0), TexCoord = new Vector2(0, 0) }, new Vertex() { Position = new Vector3(0, 1, 0), TexCoord = new Vector2(0, 1) }, new Vertex() { Position = new Vector3(1, 1, 0), TexCoord = new Vector2(1, 1) }, new Vertex() { Position = new Vector3(1, 0, 0), TexCoord = new Vector2(1, 0) } }; //init square index data uint[] squareIndices = new uint[] { 0, 1, 2, 0, 2, 3 }; //init square buffer and update mSquareVertexBuffer = new GpuBuffer( Utility.SizeOf <Vertex>() * squareVertices.Length, Utility.SizeOf <Vertex>() * 1, mDevice, GpuResourceInfo.VertexBuffer()); mSquareIndexBuffer = new GpuBuffer( Utility.SizeOf <uint>() * squareIndices.Length, Utility.SizeOf <uint>() * 1, mDevice, GpuResourceInfo.IndexBuffer()); mSquareVertexBuffer.Update(squareVertices); mSquareIndexBuffer.Update(squareIndices); //init rectangle index data uint[] rectangleIndices = new uint[] { 0, 4, 1, 1, 4, 5, 0, 3, 4, 3, 7, 4, 3, 6, 7, 2, 6, 3, 2, 1, 6, 1, 5, 6 }; //init rectangle vertex and index buffer mRectangleVertexBuffer = new GpuBuffer( Utility.SizeOf <Vertex>() * 8, Utility.SizeOf <Vertex>() * 1, mDevice, GpuResourceInfo.VertexBuffer()); mRectangleIndexBuffer = new GpuBuffer( Utility.SizeOf <uint>() * 24, Utility.SizeOf <uint>() * 1, mDevice, GpuResourceInfo.IndexBuffer()); mRectangleIndexBuffer.Update(rectangleIndices); //init shader buffer mMatrixDataBuffer = new GpuBuffer( Utility.SizeOf <MatrixData>(), Utility.SizeOf <MatrixData>(), mDevice, GpuResourceInfo.ConstantBuffer()); mRenderConfigBuffer = new GpuBuffer( Utility.SizeOf <RenderConfig>(), Utility.SizeOf <RenderConfig>(), mDevice, GpuResourceInfo.ConstantBuffer()); }
public Configure(GpuDevice device, Settings settings, GpuBindGroupLayout bindGroupLayout, GpuBindGroupLayout dynamicBindGroupLayout, GpuBindGroupLayout timeBindGroupLayout, GpuRenderPipeline pipeline, GpuRenderPipeline dynamicPipeline, GpuBuffer vertexBuffer, GpuTextureFormat swapChainFormat) { Device = device; Settings = settings; Pipeline = pipeline; DynamicPipeline = dynamicPipeline; VertexBuffer = vertexBuffer; SwapChainFormat = swapChainFormat; UniformBuffer = Device.CreateBuffer(new GpuBufferDescriptor(Settings.NumTriangles * AlignedUniformBytes + sizeof(float), GpuBufferUsageFlags.Uniform | GpuBufferUsageFlags.CopyDst)); var uniformCpuBuffer = new Windows.Storage.Streams.Buffer(Settings.NumTriangles * AlignedUniformBytes) { Length = Settings.NumTriangles * AlignedUniformBytes }; using (var uniformCpuStream = uniformCpuBuffer.AsStream()) using (var uniformCpuWriter = new BinaryWriter(uniformCpuStream)) { var rand = new Random(); for (var i = 0; i < Settings.NumTriangles; ++i) { uniformCpuWriter.Seek((int)(i * AlignedUniformBytes), SeekOrigin.Begin); float scale = (float)(rand.NextDouble() * 0.2 + 0.2); //scale = 5; float offsetX = (float)(0.9 * 2 * (rand.NextDouble() - 0.5)); float offsetY = (float)(0.9 * 2 * (rand.NextDouble() - 0.5)); float scalar = (float)(rand.NextDouble() * 1.5 + 0.5); float scalarOffset = (float)(rand.NextDouble() * 10); uniformCpuWriter.Write(scale); //Scale uniformCpuWriter.Write(offsetX); //offsetX uniformCpuWriter.Write(offsetY); //offsetY uniformCpuWriter.Write(scalar); //scalar uniformCpuWriter.Write(scalarOffset); //scalar offset } } BindGroups = new GpuBindGroup[Settings.NumTriangles]; for (var i = 0; i < Settings.NumTriangles; ++i) { BindGroups[i] = Device.CreateBindGroup(new GpuBindGroupDescriptor(bindGroupLayout, new GpuBindGroupEntry[] { new GpuBindGroupEntry(0, new GpuBufferBinding(UniformBuffer, 6 * sizeof(float)) { Offset = (UInt64)(i * AlignedUniformBytes) }) })); } DynamicBindGroup = Device.CreateBindGroup(new GpuBindGroupDescriptor(dynamicBindGroupLayout, new GpuBindGroupEntry[] { new GpuBindGroupEntry(0, new GpuBufferBinding(UniformBuffer, 6 * sizeof(float))) })); TimeBindGroup = Device.CreateBindGroup(new GpuBindGroupDescriptor(timeBindGroupLayout, new GpuBindGroupEntry[] { new GpuBindGroupEntry(0, new GpuBufferBinding(UniformBuffer, sizeof(float)) { Offset = TimeOffset }) })); Device.DefaultQueue.WriteBuffer(UniformBuffer, 0, uniformCpuBuffer); var renderBundleEncoder = Device.CreateRenderBundleEncoder(new GpuRenderBundleEncoderDescriptor(new GpuTextureFormat[] { SwapChainFormat })); RecordRenderPass(renderBundleEncoder); RenderBundle = renderBundleEncoder.Finish(); UniformTimeCpuBuffer = new Windows.Storage.Streams.Buffer(sizeof(float)) { Length = sizeof(float) }; }
async Task Init() { var gpu = new Gpu(); #if DEBUG gpu.EnableD3D12DebugLayer(); #endif Device = await(await gpu.RequestAdapterAsync()).RequestDeviceAsync(); Windows.Storage.Streams.Buffer verticeCpuBuffer = new Windows.Storage.Streams.Buffer((uint)Buffer.ByteLength(Cube.CubeVertexArray)); verticeCpuBuffer.Length = verticeCpuBuffer.Capacity; using (var verticeCpuStream = verticeCpuBuffer.AsStream()) { byte[] vertexBufferBytes = new byte[Buffer.ByteLength(Cube.CubeVertexArray)]; Buffer.BlockCopy(Cube.CubeVertexArray, 0, vertexBufferBytes, 0, Buffer.ByteLength(Cube.CubeVertexArray)); await verticeCpuStream.WriteAsync(vertexBufferBytes, 0, Buffer.ByteLength(Cube.CubeVertexArray)); } VerticesBuffer = Device.CreateBuffer(new GpuBufferDescriptor((ulong)Buffer.ByteLength(Cube.CubeVertexArray), GpuBufferUsageFlags.Vertex) { MappedAtCreation = true }); verticeCpuBuffer.CopyTo(VerticesBuffer.GetMappedRange()); VerticesBuffer.Unmap(); string shaderCode; using (var shaderFileStream = typeof(MainPage).Assembly.GetManifestResourceStream("TexturedCube.shader.hlsl")) using (var shaderStreamReader = new StreamReader(shaderFileStream)) { shaderCode = shaderStreamReader.ReadToEnd(); } var shader = Device.CreateShaderModule(new GpuShaderModuleDescriptor(GpuShaderSourceType.Hlsl, shaderCode)); var vertexState = new GpuVertexState(shader, "VSMain") { VertexBuffers = new GpuVertexBufferLayout[] { new GpuVertexBufferLayout(Cube.CubeVertexSize, new GpuVertexAttribute[] { new GpuVertexAttribute() { ShaderLocation = 0, Format = GpuVertexFormat.Float4, Offset = Cube.CubePositionOffset }, new GpuVertexAttribute() { ShaderLocation = 1, Format = GpuVertexFormat.Float2, Offset = Cube.CubeUVOffset } }) } }; var fragmentState = new GpuFragmentState(shader, "PSMain", new GpuColorTargetState[] { new GpuColorTargetState { Format = GpuTextureFormat.BGRA8UNorm, Blend = null, WriteMask = GpuColorWriteFlags.All } }); var primitiveState = new GpuPrimitiveState { Topology = GpuPrimitiveTopology.TriangleList, FrontFace = GpuFrontFace.Ccw, CullMode = GpuCullMode.Back, StripIndexFormat = null }; var depthState = new GpuDepthStencilState(GpuTextureFormat.Depth24PlusStencil8) { DepthWriteEnabled = true, DepthCompare = GpuCompareFunction.Less, }; var uniformBindGroupLayout = Device.CreateBindGroupLayout(new GpuBindGroupLayoutDescriptor(new GpuBindGroupLayoutEntry[] { new GpuBindGroupLayoutEntry() { Binding = 0, Visibility = GpuShaderStageFlags.Vertex, Buffer = new GpuBufferBindingLayout { Type = GpuBufferBindingType.Uniform, HasDynamicOffset = false, MinBindingSize = UniformBufferSize } }, new GpuBindGroupLayoutEntry() { Binding = 1, Visibility = GpuShaderStageFlags.Fragment, Sampler = new GpuSamplerBindingLayout() { Type = GpuSamplerBindingType.Filtering } }, new GpuBindGroupLayoutEntry() { Binding = 2, Visibility = GpuShaderStageFlags.Fragment, Texture = new GpuTextureBindingLayout() { SampleType = GpuTextureSampleType.Float, ViewDimension = GpuTextureViewDimension._2D, Multisampled = false } } })); var pipelineLayout = Device.CreatePipelineLayout(new GpuPipelineLayoutDescriptor() { BindGroupLayouts = new GpuBindGroupLayout[] { uniformBindGroupLayout } }); Pipeline = Device.CreateRenderPipeline(new GpuRenderPipelineDescriptor(vertexState) { Fragment = fragmentState, Primitive = primitiveState, DepthStencilState = depthState, Layout = pipelineLayout }); UniformBuffer = Device.CreateBuffer(new GpuBufferDescriptor(UniformBufferSize, GpuBufferUsageFlags.Uniform | GpuBufferUsageFlags.CopyDst)); UniformCpuBuffer = new Windows.Storage.Streams.Buffer(4 * 4 * sizeof(float)); UniformCpuBuffer.Length = UniformCpuBuffer.Capacity; var imgDecoder = await BitmapDecoder.CreateAsync(typeof(MainPage).Assembly.GetManifestResourceStream("TexturedCube.Di_3d.png").AsRandomAccessStream()); var imageBitmap = await imgDecoder.GetSoftwareBitmapAsync(); var cubeTexture = Device.CreateTexture(new GpuTextureDescriptor(new GpuExtend3DDict { Width = (uint)imageBitmap.PixelWidth, Height = (uint)imageBitmap.PixelHeight, Depth = 1 }, GpuTextureFormat.BGRA8UNorm, GpuTextureUsageFlags.Sampled | GpuTextureUsageFlags.CopyDst)); Device.DefaultQueue.CopyImageBitmapToTexture(new GpuImageCopyImageBitmap(imageBitmap), new GpuImageCopyTexture(cubeTexture), new GpuExtend3DDict { Width = (uint)imageBitmap.PixelWidth, Height = (uint)imageBitmap.PixelHeight, Depth = 1 }); var sampler = Device.CreateSampler(new GpuSamplerDescriptor() { MagFilter = GpuFilterMode.Linear, MinFilter = GpuFilterMode.Linear }); UniformBindGroup = Device.CreateBindGroup(new GpuBindGroupDescriptor(uniformBindGroupLayout, new GpuBindGroupEntry[] { new GpuBindGroupEntry(0, new GpuBufferBinding(UniformBuffer, UniformBufferSize)), new GpuBindGroupEntry(1, sampler), new GpuBindGroupEntry(2, cubeTexture.CreateView()) })); }
async Task Init() { var gpu = new Gpu(); #if DEBUG gpu.EnableD3D12DebugLayer(); #endif Device = await(await gpu.RequestAdapterAsync()).RequestDeviceAsync(); Windows.Storage.Streams.Buffer verticeCpuBuffer = new Windows.Storage.Streams.Buffer((uint)Buffer.ByteLength(Cube.CubeVertexArray)); verticeCpuBuffer.Length = verticeCpuBuffer.Capacity; using (var verticeCpuStream = verticeCpuBuffer.AsStream()) { byte[] vertexBufferBytes = new byte[Buffer.ByteLength(Cube.CubeVertexArray)]; Buffer.BlockCopy(Cube.CubeVertexArray, 0, vertexBufferBytes, 0, Buffer.ByteLength(Cube.CubeVertexArray)); await verticeCpuStream.WriteAsync(vertexBufferBytes, 0, Buffer.ByteLength(Cube.CubeVertexArray)); } VerticesBuffer = Device.CreateBuffer(new GpuBufferDescriptor((ulong)Buffer.ByteLength(Cube.CubeVertexArray), GpuBufferUsageFlags.Vertex) { MappedAtCreation = true }); verticeCpuBuffer.CopyTo(VerticesBuffer.GetMappedRange()); VerticesBuffer.Unmap(); string shaderCode; using (var shaderFileStream = typeof(MainPage).Assembly.GetManifestResourceStream("RotatingCube.shader.hlsl")) using (var shaderStreamReader = new StreamReader(shaderFileStream)) { shaderCode = shaderStreamReader.ReadToEnd(); } var shader = Device.CreateShaderModule(new GpuShaderModuleDescriptor(GpuShaderSourceType.Hlsl, shaderCode)); //var shader = Device.CreateShaderModule(new GpuShaderModuleDescriptor(GpuShaderSourceType.Hlsl, )) var vertexState = new GpuVertexState(shader, "VSMain") { VertexBuffers = new GpuVertexBufferLayout[] { new GpuVertexBufferLayout(Cube.CubeVertexSize, new GpuVertexAttribute[] { new GpuVertexAttribute() { ShaderLocation = 0, Format = GpuVertexFormat.Float4, Offset = Cube.CubePositionOffset }, new GpuVertexAttribute() { ShaderLocation = 1, Format = GpuVertexFormat.Float4, Offset = Cube.CubeColorOffset } }) } }; var fragmentState = new GpuFragmentState(shader, "PSMain", new GpuColorTargetState[] { new GpuColorTargetState { Format = GpuTextureFormat.BGRA8UNorm, Blend = null, WriteMask = GpuColorWriteFlags.All } }); var primitiveState = new GpuPrimitiveState { Topology = GpuPrimitiveTopology.TriangleList, FrontFace = GpuFrontFace.Ccw, CullMode = GpuCullMode.Back, StripIndexFormat = null }; var depthState = new GpuDepthStencilState(GpuTextureFormat.Depth24PlusStencil8) { DepthWriteEnabled = true, DepthCompare = GpuCompareFunction.Less, }; var uniformBindGroupLayout = Device.CreateBindGroupLayout(new GpuBindGroupLayoutDescriptor(new GpuBindGroupLayoutEntry[] { new GpuBindGroupLayoutEntry() { Binding = 0, Visibility = GpuShaderStageFlags.Vertex, Buffer = new GpuBufferBindingLayout { Type = GpuBufferBindingType.Uniform, HasDynamicOffset = false, MinBindingSize = UniformBufferSize } } })); var pipelineLayout = Device.CreatePipelineLayout(new GpuPipelineLayoutDescriptor() { BindGroupLayouts = new GpuBindGroupLayout[] { uniformBindGroupLayout } }); Pipeline = Device.CreateRenderPipeline(new GpuRenderPipelineDescriptor(vertexState) { Fragment = fragmentState, Primitive = primitiveState, DepthStencilState = depthState, Layout = pipelineLayout }); UniformBuffer = Device.CreateBuffer(new GpuBufferDescriptor(UniformBufferSize, GpuBufferUsageFlags.Uniform | GpuBufferUsageFlags.CopyDst)); UniformCpuBuffer = new Windows.Storage.Streams.Buffer(4 * 4 * sizeof(float)); UniformCpuBuffer.Length = UniformCpuBuffer.Capacity; UniformBindGroup = Device.CreateBindGroup(new GpuBindGroupDescriptor(uniformBindGroupLayout, new GpuBindGroupEntry[] { new GpuBindGroupEntry(0, new GpuBufferBinding(UniformBuffer, UniformBufferSize)) })); }
async Task Init() { var adapter = await Gpu.RequestAdapterAsync(); Device = await adapter.RequestDeviceAsync(); var rectVerts = new float[] { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f }; VerticesBuffer = Device.CreateBuffer(new GpuBufferDescriptor((uint)Buffer.ByteLength(rectVerts), GpuBufferUsageFlags.Vertex) { MappedAtCreation = true }); CreateBufferFromArray(rectVerts).CopyTo(VerticesBuffer.GetMappedRange()); VerticesBuffer.Unmap(); var blurBindGroupLayouts = new GpuBindGroupLayout[] { Device.CreateBindGroupLayout(new GpuBindGroupLayoutDescriptor(new GpuBindGroupLayoutEntry[] { new GpuBindGroupLayoutEntry() { Binding = 0, Visibility = GpuShaderStageFlags.Compute, Sampler = new GpuSamplerBindingLayout() { Type = GpuSamplerBindingType.Filtering } }, new GpuBindGroupLayoutEntry() { Binding = 1, Visibility = GpuShaderStageFlags.Compute, Buffer = new GpuBufferBindingLayout() { Type = GpuBufferBindingType.Uniform, HasDynamicOffset = false, MinBindingSize = 2 * 4 /* 2 uints */ } } })), Device.CreateBindGroupLayout(new GpuBindGroupLayoutDescriptor(new GpuBindGroupLayoutEntry[] { new GpuBindGroupLayoutEntry() { Binding = 1, Visibility = GpuShaderStageFlags.Compute, Texture = new GpuTextureBindingLayout() { SampleType = GpuTextureSampleType.Float, ViewDimension = GpuTextureViewDimension._2D, Multisampled = false } }, new GpuBindGroupLayoutEntry() { Binding = 2, Visibility = GpuShaderStageFlags.Compute, StorageTexture = new GpuStorageTextureBindingLayout() { Format = GpuTextureFormat.RGBA8UNorm, Access = GpuStorageTextureAccess.WriteOnly, ViewDimension = GpuTextureViewDimension._2D } }, new GpuBindGroupLayoutEntry() { Binding = 3, Visibility = GpuShaderStageFlags.Compute, Buffer = new GpuBufferBindingLayout() { Type = GpuBufferBindingType.Uniform, HasDynamicOffset = false, MinBindingSize = 4 } } })) }; GpuShaderModule computeShader; using (var shaderFileStream = typeof(MainPage).Assembly.GetManifestResourceStream("ImageBlur.compute.hlsl")) using (var shaderStreamReader = new StreamReader(shaderFileStream)) { var shaderCode = await shaderStreamReader.ReadToEndAsync(); computeShader = Device.CreateShaderModule(new GpuShaderModuleDescriptor(GpuShaderSourceType.Hlsl, shaderCode)); } GpuShaderModule drawShader; using (var shaderFileStream = typeof(MainPage).Assembly.GetManifestResourceStream("ImageBlur.draw.hlsl")) using (var shaderStreamReader = new StreamReader(shaderFileStream)) { var shaderCode = await shaderStreamReader.ReadToEndAsync(); drawShader = Device.CreateShaderModule(new GpuShaderModuleDescriptor(GpuShaderSourceType.Hlsl, shaderCode)); } BlurPipeline = Device.CreateComputePipeline(new GpuComputePipelineDescriptor(new GpuProgrammableStage(computeShader, "main")) { Layout = Device.CreatePipelineLayout(new GpuPipelineLayoutDescriptor() { BindGroupLayouts = blurBindGroupLayouts }) }); var bindGroupLayout = Device.CreateBindGroupLayout(new GpuBindGroupLayoutDescriptor(new GpuBindGroupLayoutEntry[] { new GpuBindGroupLayoutEntry() { Binding = 0, Visibility = GpuShaderStageFlags.Fragment, Sampler = new GpuSamplerBindingLayout() { Type = GpuSamplerBindingType.Filtering, } }, new GpuBindGroupLayoutEntry() { Binding = 1, Visibility = GpuShaderStageFlags.Fragment, Texture = new GpuTextureBindingLayout() { SampleType = GpuTextureSampleType.Float, ViewDimension = GpuTextureViewDimension._2D, Multisampled = false } } })); Pipeline = Device.CreateRenderPipeline(new GpuRenderPipelineDescriptor(new GpuVertexState(drawShader, "VSMain") { VertexBuffers = new GpuVertexBufferLayout[] { new GpuVertexBufferLayout(20, new GpuVertexAttribute[] { new GpuVertexAttribute() { Format = GpuVertexFormat.Float3, Offset = 0, ShaderLocation = 0 }, new GpuVertexAttribute() { Format = GpuVertexFormat.Float2, Offset = 12, ShaderLocation = 1 } }) } }) { Layout = Device.CreatePipelineLayout(new GpuPipelineLayoutDescriptor() { BindGroupLayouts = new GpuBindGroupLayout[] { bindGroupLayout } }), Fragment = new GpuFragmentState(drawShader, "PSMain", new GpuColorTargetState[] { new GpuColorTargetState() { Format = SwapChainFormat, Blend = null, WriteMask = GpuColorWriteFlags.All } }), Primitive = new GpuPrimitiveState() { Topology = GpuPrimitiveTopology.TriangleList, CullMode = GpuCullMode.None, FrontFace = GpuFrontFace.Ccw } }); var sampler = Device.CreateSampler(new GpuSamplerDescriptor() { MinFilter = GpuFilterMode.Linear, MagFilter = GpuFilterMode.Linear }); var imgDecoder = await BitmapDecoder.CreateAsync(typeof(MainPage).Assembly.GetManifestResourceStream("ImageBlur.Di_3d.png").AsRandomAccessStream()); var imageBitmap = await imgDecoder.GetSoftwareBitmapAsync(); (SrcWidth, SrcHeight) = ((uint)imageBitmap.PixelWidth, (uint)imageBitmap.PixelHeight); var cubeTexture = Device.CreateTexture(new GpuTextureDescriptor(new GpuExtend3DDict { Width = (uint)imageBitmap.PixelWidth, Height = (uint)imageBitmap.PixelHeight, Depth = 1 }, GpuTextureFormat.BGRA8UNorm, GpuTextureUsageFlags.Sampled | GpuTextureUsageFlags.CopyDst)); Device.DefaultQueue.CopyImageBitmapToTexture(new GpuImageCopyImageBitmap(imageBitmap), new GpuImageCopyTexture(cubeTexture), new GpuExtend3DDict { Width = (uint)imageBitmap.PixelWidth, Height = (uint)imageBitmap.PixelHeight, Depth = 1 }); var textures = new GpuTexture[2] { Device.CreateTexture(new GpuTextureDescriptor(new GpuExtend3DDict { Width = SrcWidth, Height = SrcHeight, Depth = 1 }, GpuTextureFormat.RGBA8UNorm, GpuTextureUsageFlags.CopyDst | GpuTextureUsageFlags.Storage | GpuTextureUsageFlags.Sampled)), Device.CreateTexture(new GpuTextureDescriptor(new GpuExtend3DDict { Width = SrcWidth, Height = SrcHeight, Depth = 1 }, GpuTextureFormat.RGBA8UNorm, GpuTextureUsageFlags.CopyDst | GpuTextureUsageFlags.Storage | GpuTextureUsageFlags.Sampled)) }; var buffer0 = Device.CreateBuffer(new GpuBufferDescriptor(4, GpuBufferUsageFlags.Uniform) { MappedAtCreation = true }); using (var stream = buffer0.GetMappedRange().AsStream()) using (var writer = new BinaryWriter(stream)) { writer.Write(0u); } buffer0.Unmap(); var buffer1 = Device.CreateBuffer(new GpuBufferDescriptor(4, GpuBufferUsageFlags.Uniform) { MappedAtCreation = true }); using (var stream = buffer1.GetMappedRange().AsStream()) using (var writer = new BinaryWriter(stream)) { writer.Write(1u); } buffer1.Unmap(); BlurParamsBuffer = Device.CreateBuffer(new GpuBufferDescriptor(8, GpuBufferUsageFlags.CopyDst | GpuBufferUsageFlags.Uniform)); ComputeConstants = Device.CreateBindGroup(new GpuBindGroupDescriptor(blurBindGroupLayouts[0], new GpuBindGroupEntry[] { new GpuBindGroupEntry(0, sampler), new GpuBindGroupEntry(1, new GpuBufferBinding(BlurParamsBuffer, BlurParamsBuffer.Size)) })); ComputeBindGroup0 = Device.CreateBindGroup(new GpuBindGroupDescriptor(blurBindGroupLayouts[1], new GpuBindGroupEntry[] { new GpuBindGroupEntry(1, cubeTexture.CreateView()), new GpuBindGroupEntry(2, textures[0].CreateView()), new GpuBindGroupEntry(3, new GpuBufferBinding(buffer0, buffer0.Size)) })); ComputeBindGroup1 = Device.CreateBindGroup(new GpuBindGroupDescriptor(blurBindGroupLayouts[1], new GpuBindGroupEntry[] { new GpuBindGroupEntry(1, textures[0].CreateView()), new GpuBindGroupEntry(2, textures[1].CreateView()), new GpuBindGroupEntry(3, new GpuBufferBinding(buffer1, buffer1.Size)) })); ComputeBindGroup2 = Device.CreateBindGroup(new GpuBindGroupDescriptor(blurBindGroupLayouts[1], new GpuBindGroupEntry[] { new GpuBindGroupEntry(1, textures[1].CreateView()), new GpuBindGroupEntry(2, textures[0].CreateView()), new GpuBindGroupEntry(3, new GpuBufferBinding(buffer0, buffer0.Size)) })); UniformBindGroup = Device.CreateBindGroup(new GpuBindGroupDescriptor(bindGroupLayout, new GpuBindGroupEntry[] { new GpuBindGroupEntry(0, sampler), new GpuBindGroupEntry(1, textures[1].CreateView()) })); }
public Mesh() { vao = new VertexArray(); vertexBuffer = new GpuBuffer(BufferTarget.Array); indexBuffer = new GpuBuffer(BufferTarget.ElementArray); }
public void UpdateBuffer <T>(GpuBuffer <T> buffer, in T data)
public PresentRender(GpuDevice device, IntPtr handle, Size size) { mHandle = handle; mDevice = device; mSwapChain = new GpuSwapChain(handle, size, GpuPixelFormat.R8G8B8A8Unknown, mDevice); mBlendState = new GpuBlendState(mDevice, new RenderTargetBlendDescription() { AlphaBlendOperation = GpuBlendOperation.Add, BlendOperation = GpuBlendOperation.Add, DestinationAlphaBlend = GpuBlendOption.InverseSourceAlpha, DestinationBlend = GpuBlendOption.InverseSourceAlpha, SourceAlphaBlend = GpuBlendOption.SourceAlpha, SourceBlend = GpuBlendOption.SourceAlpha, IsBlendEnable = true }); //compile shader mVertexShader = new GpuVertexShader(mDevice, GpuVertexShader.Compile(Properties.Resources.PresentVertexShader)); mDrawPixelShader = new GpuPixelShader(mDevice, GpuPixelShader.Compile(Properties.Resources.PresentDrawPixelShader)); mMaskPixelShader = new GpuPixelShader(mDevice, GpuPixelShader.Compile(Properties.Resources.PresentMaskPixelShader)); //create input layout, we only need to render texture mInputLayout = new GpuInputLayout(mDevice, new InputElement[] { new InputElement("POSITION", 0, 12), new InputElement("TEXCOORD", 0, 8) }, mVertexShader); //init vertex and index data Vertex[] vertices = new Vertex[] { new Vertex() { Position = new System.Numerics.Vector3(0, 0, 0), TexCoord = new System.Numerics.Vector2(0, 0) }, new Vertex() { Position = new System.Numerics.Vector3(0, 1, 0), TexCoord = new System.Numerics.Vector2(0, 1) }, new Vertex() { Position = new System.Numerics.Vector3(1, 1, 0), TexCoord = new System.Numerics.Vector2(1, 1) }, new Vertex() { Position = new System.Numerics.Vector3(1, 0, 0), TexCoord = new System.Numerics.Vector2(1, 0) } }; uint[] indices = new uint[] { 0, 1, 2, 2, 3, 0 }; //create vertex and index buffer mVertexBuffer = new GpuBuffer( Utility.SizeOf <Vertex>() * vertices.Length, Utility.SizeOf <Vertex>(), mDevice, GpuResourceInfo.VertexBuffer()); mIndexBuffer = new GpuBuffer( Utility.SizeOf <uint>() * indices.Length, Utility.SizeOf <uint>(), mDevice, GpuResourceInfo.IndexBuffer()); mVertexBuffer.Update(vertices); mIndexBuffer.Update(indices); //create constant buffer //transform buffer is used for vertex shader to do transform //render config buffer is used for pixel shader to render with opacity mTransformBuffer = new GpuBuffer( Utility.SizeOf <Transform>(), Utility.SizeOf <Transform>(), mDevice, GpuResourceInfo.ConstantBuffer()); mRenderConfigBuffer = new GpuBuffer( Utility.SizeOf <RenderConfig>(), Utility.SizeOf <RenderConfig>(), mDevice, GpuResourceInfo.ConstantBuffer()); mGpuSamplerState = new GpuSamplerState(mDevice); }
async Task Init() { var adapter = await Gpu.RequestAdapterAsync(); Device = await adapter.RequestDeviceAsync(); GpuShaderModule computeShader; using (var shaderFileStream = typeof(MainWindow).Assembly.GetManifestResourceStream("ComputeBoidsWpf.compute.hlsl")) using (var shaderStreamReader = new StreamReader(shaderFileStream)) { var shaderCode = await shaderStreamReader.ReadToEndAsync(); computeShader = Device.CreateShaderModule(new GpuShaderModuleDescriptor(GpuShaderSourceType.Hlsl, shaderCode)); } GpuShaderModule drawShader; using (var shaderFileStream = typeof(MainWindow).Assembly.GetManifestResourceStream("ComputeBoidsWpf.draw.hlsl")) using (var shaderStreamReader = new StreamReader(shaderFileStream)) { var shaderCode = await shaderStreamReader.ReadToEndAsync(); drawShader = Device.CreateShaderModule(new GpuShaderModuleDescriptor(GpuShaderSourceType.Hlsl, shaderCode)); } RenderPipeline = Device.CreateRenderPipeline(new GpuRenderPipelineDescriptor(new GpuVertexState(drawShader, "VSMain") { VertexBuffers = new GpuVertexBufferLayout[] { new GpuVertexBufferLayout(4 * 4, new GpuVertexAttribute[] { new GpuVertexAttribute() { Format = GpuVertexFormat.Float2, Offset = 0, ShaderLocation = 0 }, new GpuVertexAttribute() { Format = GpuVertexFormat.Float2, Offset = 2 * 4, ShaderLocation = 1 } }) { StepMode = GpuInputStepMode.Instance }, new GpuVertexBufferLayout(2 * 4, new GpuVertexAttribute[] { new GpuVertexAttribute() { Format = GpuVertexFormat.Float2, Offset = 0, ShaderLocation = 2 } }) } }) { Fragment = new GpuFragmentState(drawShader, "PSMain", new GpuColorTargetState[] { new GpuColorTargetState { Format = GpuTextureFormat.BGRA8UNorm, Blend = null, WriteMask = GpuColorWriteFlags.All } }), Primitive = new GpuPrimitiveState { Topology = GpuPrimitiveTopology.TriangleList, CullMode = GpuCullMode.None, FrontFace = GpuFrontFace.Ccw }, DepthStencilState = new GpuDepthStencilState(GpuTextureFormat.Depth24PlusStencil8) { DepthWriteEnabled = true, DepthCompare = GpuCompareFunction.Less, } }); var computeBindGroupLayout = Device.CreateBindGroupLayout(new GpuBindGroupLayoutDescriptor(new GpuBindGroupLayoutEntry[] { new GpuBindGroupLayoutEntry() { Binding = 0, Visibility = GpuShaderStageFlags.Compute, Buffer = new GpuBufferBindingLayout() { Type = GpuBufferBindingType.Uniform, HasDynamicOffset = false, MinBindingSize = (ulong)(SimParamData.Length * sizeof(float)) } }, new GpuBindGroupLayoutEntry() { Binding = 1, Visibility = GpuShaderStageFlags.Compute, Buffer = new GpuBufferBindingLayout() { Type = GpuBufferBindingType.ReadOnlyStorage, HasDynamicOffset = false, MinBindingSize = NumParticles * 16 } }, new GpuBindGroupLayoutEntry() { Binding = 2, Visibility = GpuShaderStageFlags.Compute, Buffer = new GpuBufferBindingLayout() { Type = GpuBufferBindingType.Storage, HasDynamicOffset = false, MinBindingSize = NumParticles * 16 } } })); ComputePipeline = Device.CreateComputePipeline(new GpuComputePipelineDescriptor(new GpuProgrammableStage(computeShader, "main")) { Layout = Device.CreatePipelineLayout(new GpuPipelineLayoutDescriptor() { BindGroupLayouts = new GpuBindGroupLayout[] { computeBindGroupLayout } }), }); VerticesBuffer = Device.CreateBuffer(new GpuBufferDescriptor((ulong)(sizeof(float) * VertexBufferData.Length), GpuBufferUsageFlags.Vertex) { MappedAtCreation = true }); using (var stream = VerticesBuffer.GetMappedRange().AsStream()) using (var binaryWriter = new BinaryWriter(stream)) { for (int i = 0; i < VertexBufferData.Length; ++i) { binaryWriter.Write(VertexBufferData[i]); } } VerticesBuffer.Unmap(); var simParamBuffer = Device.CreateBuffer(new GpuBufferDescriptor((ulong)(sizeof(float) * SimParamData.Length), GpuBufferUsageFlags.Uniform) { MappedAtCreation = true }); using (var stream = simParamBuffer.GetMappedRange().AsStream()) using (var writer = new BinaryWriter(stream)) { for (int i = 0; i < SimParamData.Length; ++i) { writer.Write(SimParamData[i]); } } simParamBuffer.Unmap(); float[] initialParticleData = new float[NumParticles * 4]; Random random = new Random(); for (var i = 0; i < NumParticles; ++i) { initialParticleData[4 * i + 0] = (float)(2 * (random.NextDouble() - 0.5f)); initialParticleData[4 * i + 1] = (float)(2 * (random.NextDouble() - 0.5f)); initialParticleData[4 * i + 2] = (float)(2 * (random.NextDouble() - 0.5f) * 0.1); initialParticleData[4 * i + 3] = (float)(2 * (random.NextDouble() - 0.5f) * 0.1); } Windows.Storage.Streams.Buffer initialParticleDataBuffer = new Windows.Storage.Streams.Buffer((uint)(sizeof(float) * initialParticleData.Length)) { Length = (uint)(sizeof(float) * initialParticleData.Length) }; using (var stream = initialParticleDataBuffer.AsStream()) using (var writer = new BinaryWriter(stream)) { for (int i = 0; i < initialParticleData.Length; ++i) { writer.Write(initialParticleData[i]); } } ParticleBuffers = new GpuBuffer[2]; for (int i = 0; i < 2; ++i) { ParticleBuffers[i] = Device.CreateBuffer(new GpuBufferDescriptor(initialParticleDataBuffer.Length, GpuBufferUsageFlags.Vertex | GpuBufferUsageFlags.Storage) { MappedAtCreation = true }); initialParticleDataBuffer.CopyTo(ParticleBuffers[i].GetMappedRange()); ParticleBuffers[i].Unmap(); } ParticleBindGroups = new GpuBindGroup[2]; for (var i = 0; i < 2; ++i) { ParticleBindGroups[i] = Device.CreateBindGroup(new GpuBindGroupDescriptor(computeBindGroupLayout, new GpuBindGroupEntry[] { new GpuBindGroupEntry(0, new GpuBufferBinding(simParamBuffer, simParamBuffer.Size)), new GpuBindGroupEntry(1, new GpuBufferBinding(ParticleBuffers[i], ParticleBuffers[i].Size)), new GpuBindGroupEntry(2, new GpuBufferBinding(ParticleBuffers[(i + 1) % 2], ParticleBuffers[(i + 1) % 2].Size)) })); } T = 0; }
public void DrawScreen(GpuBuffer gpuBuffer) { // TODO: create an external texture outputTexture.UpdateExternalTexture((IntPtr)gpuBuffer.GetGlTextureBuffer().Name()); }
public CubeVolumeShader(ModelsEx models) : base(models, GetPixelSource(), "CubeVolumeShader") { coordDstBuffer = new GpuBuffer(Marshal.SizeOf(typeof(Size3)), 1); coordShader = new ImageFramework.DirectX.Shader(ImageFramework.DirectX.Shader.Type.Compute, GetComputeSource(), "CubeCoordShader"); }
internal void CopyToBuffer(ITexture source, GpuBuffer buffer, LayerMipmapRange lm) => CopyToBuffer(source, buffer, lm, Size3.Zero);