async Task Init() { var gpu = new Gpu(); gpu.EnableD3D12DebugLayer(); 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("FractalCube.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.Float4, Offset = Cube.CubeColorOffset }, new GpuVertexAttribute() { ShaderLocation = 2, 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, }; 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; Sampler = Device.CreateSampler(new GpuSamplerDescriptor() { MinFilter = GpuFilterMode.Linear, MagFilter = GpuFilterMode.Linear }); }
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()) })); }