public override void Initialise(Device device, VulkanBufferManager bufferManager) { this.vertexShader = device.CreateVertexModule(shanq => from input in shanq.GetInput <Vertex>() from spriteData in shanq.GetInput <SpriteData>() from renderState in shanq.GetBinding <RenderState>(1) select new VertexOutput { Uv = new vec2((spriteData.AtlasPosition.x + input.Uv.x), (spriteData.AtlasPosition.y + input.Uv.y)) * renderState.SpriteSize, Position = renderState.Projection * renderState.View * spriteData.Transform * new vec4(input.Position, 0, 1) }); this.fragmentShader = device.CreateFragmentModule(shanq => from input in shanq.GetInput <FragmentInput>() from texture in shanq.GetSampler2d <vec4>(0, 0) let texColour = texture.Sample(input.Uv) select new FragmentOutput { Colour = texColour * new vec4(0.5f, 0.5f, 0.5f, 1) }); indexCount = indices.Count(); this.vertexBuffer = bufferManager.CreateBuffer <Vertex>(vertices.Length, BufferUsageFlags.TransferDestination | BufferUsageFlags.VertexBuffer, MemoryPropertyFlags.DeviceLocal); this.vertexBuffer.Update(vertices); this.indexBuffer = bufferManager.CreateBuffer <uint>(indices.Length, BufferUsageFlags.TransferDestination | BufferUsageFlags.IndexBuffer, MemoryPropertyFlags.DeviceLocal); this.indexBuffer.Update(indices); this.spriteDataBuffer = bufferManager.CreateBuffer <SpriteData>(maxInstanceCount, BufferUsageFlags.TransferDestination | BufferUsageFlags.VertexBuffer, MemoryPropertyFlags.DeviceLocal); this.spriteDataBuffer.Update(new SpriteData()); this.indirectCommandBuffer = bufferManager.CreateBuffer <DrawIndexedIndirectCommand>(1, BufferUsageFlags.TransferDestination | BufferUsageFlags.IndirectBuffer, MemoryPropertyFlags.DeviceLocal); this.renderStateBuffer = bufferManager.CreateBuffer <RenderState>(1, BufferUsageFlags.TransferDestination | BufferUsageFlags.UniformBuffer, MemoryPropertyFlags.DeviceLocal); const string building = ".\\textures\\iso-64x64-building.png"; const string cube = ".\\textures\\cube.png"; var textureSource = SixLabors.ImageSharp.Image.Load(cube); uint textureWidth = (uint)textureSource.Width; uint textureHeight = (uint)textureSource.Height; DeviceSize imageSize = textureWidth * textureHeight * 4; using (var stagingImage = bufferManager.CreateImage(textureWidth, textureHeight, Format.R8G8B8A8UNorm, ImageTiling.Linear, ImageUsageFlags.TransferSource, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent, true)) { IntPtr memoryBuffer = stagingImage.Map(); unsafe { fixed(byte *rgbaPointer = textureSource.SavePixelData()) { System.Buffer.MemoryCopy(rgbaPointer, memoryBuffer.ToPointer(), imageSize, imageSize); } } stagingImage.Unmap(); this.textureImage = bufferManager.CreateImage(textureWidth, textureHeight, Format.R8G8B8A8UNorm, ImageTiling.Optimal, ImageUsageFlags.TransferDestination | ImageUsageFlags.Sampled, MemoryPropertyFlags.DeviceLocal, false); stagingImage.TransitionImageLayout(ImageLayout.Preinitialized, ImageLayout.TransferSourceOptimal); this.textureImage.TransitionImageLayout(ImageLayout.Undefined, ImageLayout.TransferDestinationOptimal); stagingImage.Copy(this.textureImage, textureWidth, textureHeight); this.textureImage.TransitionImageLayout(ImageLayout.TransferDestinationOptimal, ImageLayout.ShaderReadOnlyOptimal); } this.textureImageView = device.CreateImageView(this.textureImage.Image, ImageViewType.ImageView2d, Format.R8G8B8A8UNorm, ComponentMapping.Identity, new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1)); this.textureSampler = device.CreateSampler(Filter.Nearest, Filter.Nearest, SamplerMipmapMode.Nearest, SamplerAddressMode.ClampToBorder, SamplerAddressMode.ClampToBorder, SamplerAddressMode.ClampToBorder, 0, false, 1, false, CompareOp.Always, 0, 0, BorderColor.FloatTransparentBlack, true); this.descriptorPool = device.CreateDescriptorPool(2, new[] { new DescriptorPoolSize { DescriptorCount = 2, Type = DescriptorType.UniformBuffer }, new DescriptorPoolSize { DescriptorCount = 2, Type = DescriptorType.CombinedImageSampler } }); this.descriptorSetLayout = device.CreateDescriptorSetLayout( new[] { new DescriptorSetLayoutBinding { Binding = 0, DescriptorCount = 1, DescriptorType = DescriptorType.CombinedImageSampler, StageFlags = ShaderStageFlags.Fragment }, new DescriptorSetLayoutBinding { Binding = 1, DescriptorCount = 1, DescriptorType = DescriptorType.UniformBuffer, StageFlags = ShaderStageFlags.Vertex } }); this.pipelineLayout = device.CreatePipelineLayout(this.descriptorSetLayout, null); this.descriptorSet = device.AllocateDescriptorSet(descriptorPool, this.descriptorSetLayout); device.UpdateDescriptorSets(new[] { new WriteDescriptorSet { ImageInfo = new [] { new DescriptorImageInfo { ImageView = textureImageView, Sampler = textureSampler, ImageLayout = ImageLayout.ShaderReadOnlyOptimal } }, DescriptorCount = 1, DestinationSet = this.descriptorSet, DestinationBinding = 0, DestinationArrayElement = 0, DescriptorType = DescriptorType.CombinedImageSampler }, new WriteDescriptorSet { BufferInfo = new[] { new DescriptorBufferInfo { Buffer = this.renderStateBuffer.Buffer, Offset = 0, Range = Constants.WholeSize } }, DescriptorCount = 1, DestinationSet = this.descriptorSet, DestinationBinding = 1, DestinationArrayElement = 0, DescriptorType = DescriptorType.UniformBuffer } }, null); }
public void Copy(VulkanImage destination, uint width, uint height) { this.manager.Copy(this.image, destination.image, width, height); }