public static Texture2D RenderTarget(Graphics g, int width, int height) { const Format format = Format.B8G8R8A8UNorm; // Create optimal tiled target image. Image image = g.Context.Device.CreateImage(new ImageCreateInfo { ImageType = ImageType.Image2D, Format = format, MipLevels = 1, ArrayLayers = 1, Samples = SampleCounts.Count1, Tiling = ImageTiling.Optimal, SharingMode = SharingMode.Exclusive, InitialLayout = ImageLayout.Undefined, Extent = new Extent3D(width, height, 1), Usage = ImageUsages.Sampled | ImageUsages.TransferDst | ImageUsages.TransferSrc | ImageUsages.ColorAttachment }); MemoryRequirements imageMemReq = image.GetMemoryRequirements(); int imageHeapIndex = g.Context.MemoryProperties.MemoryTypes.IndexOf( imageMemReq.MemoryTypeBits, MemoryProperties.DeviceLocal); DeviceMemory memory = g.Context.Device.AllocateMemory(new MemoryAllocateInfo(imageMemReq.Size, imageHeapIndex)); image.BindMemory(memory); var subresourceRange = new ImageSubresourceRange(ImageAspects.Color, 0, 1, 0, 1); // Create image view. ImageView view = image.CreateView(new ImageViewCreateInfo(format, subresourceRange)); var sampler = VKHelper.CreateSampler(g.Context, Filter.Linear, Filter.Linear, SamplerMipmapMode.Linear); return(new Texture2D(g.Context, image, memory, view, format, new Vector2I(width, height), true)); }
public static DescriptorItem CombinedImageSampler(ShaderType shaderType, Texture2D texture, SamplerFilter minFilter, SamplerFilter magFilter, SamplerFilter mipmapFilter = SamplerFilter.Nearest) { var item = new DescriptorItem(); item.Type = DescriptorType.CombinedImageSampler; item.Shader = shaderType; item.Texture = texture; item.Sampler = VKHelper.CreateSampler( texture.Context, minFilter == SamplerFilter.Nearest ? Filter.Nearest : minFilter == SamplerFilter.Cubic ? Filter.CubicImg : Filter.Linear, magFilter == SamplerFilter.Nearest ? Filter.Nearest : magFilter == SamplerFilter.Cubic ? Filter.CubicImg : Filter.Linear, mipmapFilter == SamplerFilter.Linear ? SamplerMipmapMode.Linear : SamplerMipmapMode.Nearest ); return(item); }
internal static Texture2D FromTextureData(Context ctx, TextureData tex2D) { var stagingBuffer = ctx.Device.CreateBuffer( new BufferCreateInfo(tex2D.Mipmaps[0].Size, BufferUsages.TransferSrc)); MemoryRequirements stagingMemReq = stagingBuffer.GetMemoryRequirements(); int heapIndex = ctx.MemoryProperties.MemoryTypes.IndexOf( stagingMemReq.MemoryTypeBits, MemoryProperties.HostVisible); DeviceMemory stagingMemory = ctx.Device.AllocateMemory( new MemoryAllocateInfo(stagingMemReq.Size, heapIndex)); stagingBuffer.BindMemory(stagingMemory); unsafe { var dest = (byte *)stagingMemory.Map(0, stagingMemReq.Size); var src = (byte *)tex2D.Mipmaps[0].Data.Scan0; for (var i = 0; i < stagingMemReq.Size - 3; i += 4) { *(dest + 2) = *(src++); *(dest + 1) = *(src++); *(dest) = *(src++); *(dest + 3) = *(src++); dest += 4; } } //Interop.Write(ptr, tex2D.Mipmaps[0].Data); stagingMemory.Unmap(); // Setup buffer copy regions for each mip level. var bufferCopyRegions = new BufferImageCopy[tex2D.Mipmaps.Length]; int offset = 0; for (int i = 0; i < bufferCopyRegions.Length; i++) { bufferCopyRegions = new[] { new BufferImageCopy { ImageSubresource = new ImageSubresourceLayers(ImageAspects.Color, i, 0, 1), ImageExtent = tex2D.Mipmaps[0].Extent, BufferOffset = offset } }; offset += tex2D.Mipmaps[i].Size; } // Create optimal tiled target image. Image image = ctx.Device.CreateImage(new ImageCreateInfo { ImageType = ImageType.Image2D, Format = tex2D.Format, MipLevels = tex2D.Mipmaps.Length, ArrayLayers = 1, Samples = SampleCounts.Count1, Tiling = ImageTiling.Optimal, SharingMode = SharingMode.Exclusive, InitialLayout = ImageLayout.Undefined, Extent = tex2D.Mipmaps[0].Extent, Usage = ImageUsages.Sampled | ImageUsages.TransferDst }); MemoryRequirements imageMemReq = image.GetMemoryRequirements(); int imageHeapIndex = ctx.MemoryProperties.MemoryTypes.IndexOf( imageMemReq.MemoryTypeBits, MemoryProperties.DeviceLocal); DeviceMemory memory = ctx.Device.AllocateMemory(new MemoryAllocateInfo(imageMemReq.Size, imageHeapIndex)); image.BindMemory(memory); var subresourceRange = new ImageSubresourceRange(ImageAspects.Color, 0, tex2D.Mipmaps.Length, 0, 1); // Copy the data from staging buffers to device local buffers. CommandBuffer cmdBuffer = ctx.GraphicsCommandPool.AllocateBuffers(new CommandBufferAllocateInfo(CommandBufferLevel.Primary, 1))[0]; cmdBuffer.Begin(new CommandBufferBeginInfo(CommandBufferUsages.OneTimeSubmit)); cmdBuffer.CmdPipelineBarrier(PipelineStages.TopOfPipe, PipelineStages.Transfer, imageMemoryBarriers: new[] { new ImageMemoryBarrier( image, subresourceRange, 0, Accesses.TransferWrite, ImageLayout.Undefined, ImageLayout.TransferDstOptimal) }); cmdBuffer.CmdCopyBufferToImage(stagingBuffer, image, ImageLayout.TransferDstOptimal, bufferCopyRegions); cmdBuffer.CmdPipelineBarrier(PipelineStages.Transfer, PipelineStages.FragmentShader, imageMemoryBarriers: new[] { new ImageMemoryBarrier( image, subresourceRange, Accesses.TransferWrite, Accesses.ShaderRead, ImageLayout.TransferDstOptimal, ImageLayout.ShaderReadOnlyOptimal) }); cmdBuffer.End(); // Submit. Fence fence = ctx.Device.CreateFence(); ctx.GraphicsQueue.Submit(new SubmitInfo(commandBuffers: new[] { cmdBuffer }), fence); fence.Wait(); // Cleanup staging resources. fence.Dispose(); stagingMemory.Dispose(); stagingBuffer.Dispose(); // Create image view. ImageView view = image.CreateView(new ImageViewCreateInfo(tex2D.Format, subresourceRange)); var sampler = VKHelper.CreateSampler(ctx, Filter.Linear, Filter.Linear, SamplerMipmapMode.Linear); return(new Texture2D(ctx, image, memory, view, tex2D.Format, new Vector2I(tex2D.Mipmaps[0].Extent.Width, tex2D.Mipmaps[0].Extent.Height), false)); }