private static unsafe VkSurfaceKHR CreateNSWindowSurface(VkGraphicsDevice gd, VkInstance instance, NSWindowSwapchainSource nsWindowSource, bool hasExtMetalSurface) { CAMetalLayer metalLayer = CAMetalLayer.New(); NSWindow nswindow = new NSWindow(nsWindowSource.NSWindow); NSView contentView = nswindow.contentView; contentView.wantsLayer = true; contentView.layer = metalLayer.NativePtr; if (hasExtMetalSurface) { VkMetalSurfaceCreateInfoEXT surfaceCI = new VkMetalSurfaceCreateInfoEXT(); surfaceCI.sType = VkMetalSurfaceCreateInfoEXT.VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; surfaceCI.pLayer = metalLayer.NativePtr.ToPointer(); VkSurfaceKHR surface; VkResult result = gd.CreateMetalSurfaceEXT(instance, &surfaceCI, null, &surface); CheckResult(result); return(surface); } else { VkMacOSSurfaceCreateInfoMVK surfaceCI = VkMacOSSurfaceCreateInfoMVK.New(); surfaceCI.pView = contentView.NativePtr.ToPointer(); VkResult result = vkCreateMacOSSurfaceMVK(instance, ref surfaceCI, null, out VkSurfaceKHR surface); CheckResult(result); return(surface); } }
private static VkSurfaceKHR CreateUIViewSurface(VkGraphicsDevice gd, VkInstance instance, UIViewSwapchainSource uiViewSource, bool hasExtMetalSurface) { CAMetalLayer metalLayer = CAMetalLayer.New(); UIView uiView = new UIView(uiViewSource.UIView); metalLayer.frame = uiView.frame; metalLayer.opaque = true; uiView.layer.addSublayer(metalLayer.NativePtr); if (hasExtMetalSurface) { VkMetalSurfaceCreateInfoEXT surfaceCI = new VkMetalSurfaceCreateInfoEXT(); surfaceCI.sType = VkMetalSurfaceCreateInfoEXT.VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; surfaceCI.pLayer = metalLayer.NativePtr.ToPointer(); VkSurfaceKHR surface; VkResult result = gd.CreateMetalSurfaceEXT(instance, &surfaceCI, null, &surface); CheckResult(result); return(surface); } else { VkIOSSurfaceCreateInfoMVK surfaceCI = VkIOSSurfaceCreateInfoMVK.New(); surfaceCI.pView = uiView.NativePtr.ToPointer(); VkResult result = vkCreateIOSSurfaceMVK(instance, ref surfaceCI, null, out VkSurfaceKHR surface); return(surface); } }
internal VkTexture( VkGraphicsDevice gd, uint width, uint height, uint mipLevels, uint arrayLayers, VkFormat vkFormat, TextureUsage usage, TextureSampleCount sampleCount, VkImage existingImage) { Debug.Assert(width > 0 && height > 0); _gd = gd; MipLevels = mipLevels; Width = width; Height = height; Depth = 1; VkFormat = vkFormat; Format = VkFormats.VkToVdPixelFormat(VkFormat); ArrayLayers = arrayLayers; Usage = usage; SampleCount = sampleCount; VkSampleCount = VkFormats.VdToVkSampleCount(sampleCount); _optimalImage = existingImage; }
// Used to construct Swapchain textures. internal VkTexture( VkGraphicsDevice gd, uint width, uint height, uint mipLevels, uint arrayLayers, VkFormat vkFormat, TextureUsage usage, TextureSampleCount sampleCount, VkImage existingImage) { Debug.Assert(width > 0 && height > 0); _gd = gd; MipLevels = mipLevels; _width = width; _height = height; _depth = 1; VkFormat = vkFormat; _format = VkFormats.VkToVdPixelFormat(VkFormat); ArrayLayers = arrayLayers; Usage = usage; Type = TextureType.Texture2D; SampleCount = sampleCount; VkSampleCount = VkFormats.VdToVkSampleCount(sampleCount); _optimalImage = existingImage; _imageLayouts = new[] { VkImageLayout.Undefined }; ClearIfRenderTarget(); }
public VkResourceLayout(VkGraphicsDevice gd, ref ResourceLayoutDescription description) { _gd = gd; VkDescriptorSetLayoutCreateInfo dslCI = VkDescriptorSetLayoutCreateInfo.New(); ResourceLayoutElementDescription[] elements = description.Elements; _descriptorTypes = new VkDescriptorType[elements.Length]; VkDescriptorSetLayoutBinding *bindings = stackalloc VkDescriptorSetLayoutBinding[elements.Length]; for (uint i = 0; i < elements.Length; i++) { bindings[i].binding = i; bindings[i].descriptorCount = 1; VkDescriptorType descriptorType = VkFormats.VdToVkDescriptorType(elements[i].Kind); bindings[i].descriptorType = descriptorType; bindings[i].stageFlags = VkFormats.VdToVkShaderStages(elements[i].Stages); _descriptorTypes[i] = descriptorType; } dslCI.bindingCount = (uint)elements.Length; dslCI.pBindings = bindings; VkResult result = vkCreateDescriptorSetLayout(_gd.Device, ref dslCI, null, out _dsl); CheckResult(result); }
public VkBuffer(VkGraphicsDevice gd, uint sizeInBytes, BufferUsage usage) { _gd = gd; SizeInBytes = sizeInBytes; Usage = usage; VkBufferUsageFlags vkUsage = VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst; if ((usage & BufferUsage.VertexBuffer) == BufferUsage.VertexBuffer) { vkUsage |= VkBufferUsageFlags.VertexBuffer; } if ((usage & BufferUsage.IndexBuffer) == BufferUsage.IndexBuffer) { vkUsage |= VkBufferUsageFlags.IndexBuffer; } if ((usage & BufferUsage.UniformBuffer) == BufferUsage.UniformBuffer) { vkUsage |= VkBufferUsageFlags.UniformBuffer; } if ((usage & BufferUsage.StructuredBufferReadWrite) == BufferUsage.StructuredBufferReadWrite || (usage & BufferUsage.StructuredBufferReadOnly) == BufferUsage.StructuredBufferReadOnly) { vkUsage |= VkBufferUsageFlags.StorageBuffer; } if ((usage & BufferUsage.IndirectBuffer) == BufferUsage.IndirectBuffer) { vkUsage |= VkBufferUsageFlags.IndirectBuffer; } VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New(); bufferCI.size = sizeInBytes; bufferCI.usage = vkUsage; VkResult result = vkCreateBuffer(gd.Device, ref bufferCI, null, out _deviceBuffer); CheckResult(result); vkGetBufferMemoryRequirements(gd.Device, _deviceBuffer, out _bufferMemoryRequirements); bool hostVisible = (usage & BufferUsage.Dynamic) == BufferUsage.Dynamic || (usage & BufferUsage.Staging) == BufferUsage.Staging; VkMemoryPropertyFlags memoryPropertyFlags = hostVisible ? VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent : VkMemoryPropertyFlags.DeviceLocal; VkMemoryBlock memoryToken = gd.MemoryManager.Allocate( gd.PhysicalDeviceMemProperties, _bufferMemoryRequirements.memoryTypeBits, memoryPropertyFlags, hostVisible, _bufferMemoryRequirements.size, _bufferMemoryRequirements.alignment); _memory = memoryToken; result = vkBindBufferMemory(gd.Device, _deviceBuffer, _memory.DeviceMemory, _memory.Offset); CheckResult(result); }
public VkBuffer(VkGraphicsDevice gd, ulong sizeInBytes, bool dynamic, VkBufferUsageFlags usage) { _gd = gd; SizeInBytes = sizeInBytes; usage |= VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst; VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New(); bufferCI.size = sizeInBytes; bufferCI.usage = usage; VkResult result = vkCreateBuffer(gd.Device, ref bufferCI, null, out _deviceBuffer); CheckResult(result); vkGetBufferMemoryRequirements(gd.Device, _deviceBuffer, out VkMemoryRequirements bufferMemoryRequirements); VkMemoryBlock memoryToken = gd.MemoryManager.Allocate( gd.PhysicalDeviceMemProperties, bufferMemoryRequirements.memoryTypeBits, VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent, dynamic, bufferMemoryRequirements.size, bufferMemoryRequirements.alignment); _memory = memoryToken; result = vkBindBufferMemory(gd.Device, _deviceBuffer, _memory.DeviceMemory, _memory.Offset); CheckResult(result); }
public VkSampler(VkGraphicsDevice gd, ref SamplerDescription description) { _gd = gd; VkFormats.GetFilterParams(description.Filter, out VkFilter minFilter, out VkFilter magFilter, out VkSamplerMipmapMode mipmapMode); VkSamplerCreateInfo samplerCI = new VkSamplerCreateInfo { sType = VkStructureType.SamplerCreateInfo, addressModeU = VkFormats.VdToVkSamplerAddressMode(description.AddressModeU), addressModeV = VkFormats.VdToVkSamplerAddressMode(description.AddressModeV), addressModeW = VkFormats.VdToVkSamplerAddressMode(description.AddressModeW), minFilter = minFilter, magFilter = magFilter, mipmapMode = mipmapMode, compareEnable = description.ComparisonKind != null, compareOp = description.ComparisonKind != null ? VkFormats.VdToVkCompareOp(description.ComparisonKind.Value) : VkCompareOp.Never, anisotropyEnable = description.Filter == SamplerFilter.Anisotropic, maxAnisotropy = description.MaximumAnisotropy, minLod = description.MinimumLod, maxLod = description.MaximumLod, mipLodBias = description.LodBias, borderColor = VkFormats.VdToVkSamplerBorderColor(description.BorderColor) }; vkCreateSampler(_gd.Device, ref samplerCI, null, out _sampler); RefCount = new ResourceRefCount(DisposeCore); }
internal static VkSurfaceKHR CreateSurface(VkGraphicsDevice gd, VkInstance instance, SwapchainSource swapchainSource) { // TODO a null GD is passed from VkSurfaceSource.CreateSurface for compatibility // when VkSurfaceInfo is removed we do not have to handle gd == null anymore var doCheck = gd != null; if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_KHR_SURFACE_EXTENSION_NAME)) { throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_SURFACE_EXTENSION_NAME}"); } switch (swapchainSource) { case XlibSwapchainSource xlibSource: if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_KHR_XLIB_SURFACE_EXTENSION_NAME)) { throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_XLIB_SURFACE_EXTENSION_NAME}"); } return(CreateXlib(instance, xlibSource)); case WaylandSwapchainSource waylandSource: if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME)) { throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME}"); } return(CreateWayland(instance, waylandSource)); case Win32SwapchainSource win32Source: if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_KHR_WIN32_SURFACE_EXTENSION_NAME)) { throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_WIN32_SURFACE_EXTENSION_NAME}"); } return(CreateWin32(instance, win32Source)); case AndroidSurfaceSwapchainSource androidSource: if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_KHR_ANDROID_SURFACE_EXTENSION_NAME)) { throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_KHR_ANDROID_SURFACE_EXTENSION_NAME}"); } return(CreateAndroidSurface(instance, androidSource)); case NSWindowSwapchainSource nsWindowSource: if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_MVK_MACOS_SURFACE_EXTENSION_NAME)) { throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_MVK_MACOS_SURFACE_EXTENSION_NAME}"); } return(CreateNSWindowSurface(instance, nsWindowSource)); case UIViewSwapchainSource uiViewSource: if (doCheck && !gd.HasSurfaceExtension(CommonStrings.VK_MVK_IOS_SURFACE_EXTENSION_NAME)) { throw new VeldridException($"The required instance extension was not available: {CommonStrings.VK_MVK_IOS_SURFACE_EXTENSION_NAME}"); } return(CreateUIViewSurface(instance, uiViewSource)); default: throw new VeldridException($"The provided SwapchainSource cannot be used to create a Vulkan surface."); } }
public VkSwapchainFramebuffer(VkGraphicsDevice gd, VkSurfaceKHR surface, uint width, uint height) : base() { _gd = gd; _surface = surface; CreateSwapchain(width, height); OutputDescription = OutputDescription.CreateFromFramebuffer(this); }
public VkTextureView(VkGraphicsDevice gd, ref TextureViewDescription description) : base(ref description) { _gd = gd; VkImageViewCreateInfo imageViewCI = VkImageViewCreateInfo.New(); VkTexture tex = Util.AssertSubtype <Texture, VkTexture>(description.Target); imageViewCI.image = tex.OptimalDeviceImage; imageViewCI.format = VkFormats.VdToVkPixelFormat(Format, (Target.Usage & TextureUsage.DepthStencil) != 0); VkImageAspectFlags aspectFlags; if ((description.Target.Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil) { aspectFlags = VkImageAspectFlags.Depth; } else { aspectFlags = VkImageAspectFlags.Color; } imageViewCI.subresourceRange = new VkImageSubresourceRange( aspectFlags, description.BaseMipLevel, description.MipLevels, description.BaseArrayLayer, description.ArrayLayers); if ((tex.Usage & TextureUsage.Cubemap) == TextureUsage.Cubemap) { imageViewCI.viewType = description.ArrayLayers == 1 ? VkImageViewType.ImageCube : VkImageViewType.ImageCubeArray; imageViewCI.subresourceRange.layerCount *= 6; } else { switch (tex.Type) { case TextureType.Texture1D: imageViewCI.viewType = description.ArrayLayers == 1 ? VkImageViewType.Image1D : VkImageViewType.Image1DArray; break; case TextureType.Texture2D: imageViewCI.viewType = description.ArrayLayers == 1 ? VkImageViewType.Image2D : VkImageViewType.Image2DArray; break; case TextureType.Texture3D: imageViewCI.viewType = VkImageViewType.Image3D; break; } } vkCreateImageView(_gd.Device, ref imageViewCI, null, out _imageView); RefCount = new ResourceRefCount(DisposeCore); }
public VkResourceSet(VkGraphicsDevice gd, ref ResourceSetDescription description) : base(ref description) { _gd = gd; VkResourceLayout vkLayout = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(description.Layout); VkDescriptorSetLayout dsl = vkLayout.DescriptorSetLayout; _descriptorCounts = vkLayout.DescriptorResourceCounts; _descriptorAllocationToken = _gd.DescriptorPoolManager.Allocate(_descriptorCounts, dsl); BindableResource[] boundResources = description.BoundResources; uint descriptorWriteCount = (uint)boundResources.Length; VkWriteDescriptorSet * descriptorWrites = stackalloc VkWriteDescriptorSet[(int)descriptorWriteCount]; VkDescriptorBufferInfo *bufferInfos = stackalloc VkDescriptorBufferInfo[(int)descriptorWriteCount]; VkDescriptorImageInfo * imageInfos = stackalloc VkDescriptorImageInfo[(int)descriptorWriteCount]; for (int i = 0; i < descriptorWriteCount; i++) { VkDescriptorType type = vkLayout.DescriptorTypes[i]; descriptorWrites[i].sType = VkStructureType.WriteDescriptorSet; descriptorWrites[i].descriptorCount = 1; descriptorWrites[i].descriptorType = type; descriptorWrites[i].dstBinding = (uint)i; descriptorWrites[i].dstSet = _descriptorAllocationToken.Set; if (type == VkDescriptorType.UniformBuffer || type == VkDescriptorType.StorageBuffer) { VkBuffer vkBuffer = Util.AssertSubtype <BindableResource, VkBuffer>(boundResources[i]); bufferInfos[i].buffer = vkBuffer.DeviceBuffer; bufferInfos[i].range = vkBuffer.SizeInBytes; descriptorWrites[i].pBufferInfo = &bufferInfos[i]; } else if (type == VkDescriptorType.SampledImage) { VkTextureView textureView = Util.AssertSubtype <BindableResource, VkTextureView>(boundResources[i]); imageInfos[i].imageView = textureView.ImageView; imageInfos[i].imageLayout = VkImageLayout.ShaderReadOnlyOptimal; descriptorWrites[i].pImageInfo = &imageInfos[i]; } else if (type == VkDescriptorType.StorageImage) { VkTextureView textureView = Util.AssertSubtype <BindableResource, VkTextureView>(boundResources[i]); imageInfos[i].imageView = textureView.ImageView; imageInfos[i].imageLayout = VkImageLayout.General; descriptorWrites[i].pImageInfo = &imageInfos[i]; } else if (type == VkDescriptorType.Sampler) { VkSampler sampler = Util.AssertSubtype <BindableResource, VkSampler>(boundResources[i]); imageInfos[i].sampler = sampler.DeviceSampler; descriptorWrites[i].pImageInfo = &imageInfos[i]; } } vkUpdateDescriptorSets(_gd.Device, descriptorWriteCount, descriptorWrites, 0, null); }
public VkResourceSet(VkGraphicsDevice gd, ref ResourceSetDescription description) { _gd = gd; VkResourceLayout vkLayout = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(description.Layout); VkDescriptorSetAllocateInfo dsAI = VkDescriptorSetAllocateInfo.New(); dsAI.descriptorSetCount = 1; VkDescriptorSetLayout dsl = vkLayout.DescriptorSetLayout; dsAI.pSetLayouts = &dsl; dsAI.descriptorPool = _gd.SharedDescriptorPool; VkResult result = vkAllocateDescriptorSets(_gd.Device, ref dsAI, out _descriptorSet); CheckResult(result); BindableResource[] boundResources = description.BoundResources; uint descriptorWriteCount = (uint)boundResources.Length; VkWriteDescriptorSet * descriptorWrites = stackalloc VkWriteDescriptorSet[(int)descriptorWriteCount]; VkDescriptorBufferInfo *bufferInfos = stackalloc VkDescriptorBufferInfo[(int)descriptorWriteCount]; VkDescriptorImageInfo * imageInfos = stackalloc VkDescriptorImageInfo[(int)descriptorWriteCount]; for (int i = 0; i < descriptorWriteCount; i++) { VkDescriptorType type = vkLayout.DescriptorTypes[i]; descriptorWrites[i].sType = VkStructureType.WriteDescriptorSet; descriptorWrites[i].descriptorCount = 1; descriptorWrites[i].descriptorType = type; descriptorWrites[i].dstBinding = (uint)i; descriptorWrites[i].dstSet = _descriptorSet; if (type == VkDescriptorType.UniformBuffer) { VkUniformBuffer uniformBuffer = Util.AssertSubtype <BindableResource, VkUniformBuffer>(boundResources[i]); bufferInfos[i].buffer = uniformBuffer.DeviceBuffer; bufferInfos[i].range = uniformBuffer.SizeInBytes; descriptorWrites[i].pBufferInfo = &bufferInfos[i]; } else if (type == VkDescriptorType.SampledImage) { VkTextureView textureView = Util.AssertSubtype <BindableResource, VkTextureView>(boundResources[i]); imageInfos[i].imageView = textureView.ImageView; imageInfos[i].imageLayout = VkImageLayout.ShaderReadOnlyOptimal; descriptorWrites[i].pImageInfo = &imageInfos[i]; } else if (type == VkDescriptorType.Sampler) { VkSampler sampler = Util.AssertSubtype <BindableResource, VkSampler>(boundResources[i]); imageInfos[i].sampler = sampler.DeviceSampler; descriptorWrites[i].pImageInfo = &imageInfos[i]; } } vkUpdateDescriptorSets(_gd.Device, descriptorWriteCount, descriptorWrites, 0, null); }
public VkFence(VkGraphicsDevice gd, bool signaled) { _gd = gd; VkFenceCreateInfo fenceCI = VkFenceCreateInfo.New(); fenceCI.flags = signaled ? VkFenceCreateFlags.Signaled : VkFenceCreateFlags.None; VkResult result = vkCreateFence(_gd.Device, ref fenceCI, null, out _fence); VulkanUtil.CheckResult(result); }
public VkCommandList(VkGraphicsDevice gd, ref CommandListDescription description) : base(ref description, gd.Features) { _gd = gd; VkCommandPoolCreateInfo poolCI = VkCommandPoolCreateInfo.New(); poolCI.flags = VkCommandPoolCreateFlags.ResetCommandBuffer; poolCI.queueFamilyIndex = gd.GraphicsQueueIndex; VkResult result = vkCreateCommandPool(_gd.Device, ref poolCI, null, out _pool); CheckResult(result); _cb = GetNextCommandBuffer(); }
public VkSwapchainFramebuffer( VkGraphicsDevice gd, VkSurfaceKHR surface, uint width, uint height, PixelFormat?depthFormat) : base() { _gd = gd; _surface = surface; _depthFormat = depthFormat; AttachmentCount = depthFormat.HasValue ? 2u : 1u; // 1 Color + 1 Depth }
public VkShader(VkGraphicsDevice gd, ref ShaderDescription description) { _gd = gd; VkShaderModuleCreateInfo shaderModuleCI = VkShaderModuleCreateInfo.New(); fixed(byte *codePtr = description.ShaderBytes) { shaderModuleCI.codeSize = (UIntPtr)description.ShaderBytes.Length; shaderModuleCI.pCode = (uint *)codePtr; VkResult result = vkCreateShaderModule(gd.Device, ref shaderModuleCI, null, out _shaderModule); CheckResult(result); } }
public VkPipeline(VkGraphicsDevice gd, ref ComputePipelineDescription description) : base(ref description) { _gd = gd; IsComputePipeline = true; VkComputePipelineCreateInfo pipelineCI = VkComputePipelineCreateInfo.New(); // Pipeline Layout ResourceLayout[] resourceLayouts = description.ResourceLayouts; VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New(); pipelineLayoutCI.setLayoutCount = (uint)resourceLayouts.Length; VkDescriptorSetLayout *dsls = stackalloc VkDescriptorSetLayout[resourceLayouts.Length]; for (int i = 0; i < resourceLayouts.Length; i++) { dsls[i] = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(resourceLayouts[i]).DescriptorSetLayout; } pipelineLayoutCI.pSetLayouts = dsls; vkCreatePipelineLayout(_gd.Device, ref pipelineLayoutCI, null, out _pipelineLayout); pipelineCI.layout = _pipelineLayout; // Shader Stage Shader shader = description.ComputeShader; VkShader vkShader = Util.AssertSubtype <Shader, VkShader>(shader); VkPipelineShaderStageCreateInfo stageCI = VkPipelineShaderStageCreateInfo.New(); stageCI.module = vkShader.ShaderModule; stageCI.stage = VkFormats.VdToVkShaderStages(shader.Stage); stageCI.pName = CommonStrings.main; // Meh pipelineCI.stage = stageCI; VkResult result = vkCreateComputePipelines( _gd.Device, VkPipelineCache.Null, 1, ref pipelineCI, null, out _devicePipeline); CheckResult(result); ResourceSetCount = (uint)description.ResourceLayouts.Length; }
public VkTextureView(VkGraphicsDevice gd, ref TextureViewDescription description) : base(ref description) { _gd = gd; VkImageViewCreateInfo imageViewCI = VkImageViewCreateInfo.New(); VkTexture tex = Util.AssertSubtype <Texture, VkTexture>(description.Target); imageViewCI.image = tex.OptimalDeviceImage; imageViewCI.format = tex.VkFormat; VkImageAspectFlags aspectFlags; if ((description.Target.Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil) { aspectFlags = VkImageAspectFlags.Depth; } else { aspectFlags = VkImageAspectFlags.Color; } imageViewCI.subresourceRange = new VkImageSubresourceRange( aspectFlags, description.BaseMipLevel, description.MipLevels, description.BaseArrayLayer, description.ArrayLayers); if ((tex.Usage & TextureUsage.Cubemap) == TextureUsage.Cubemap) { imageViewCI.viewType = description.ArrayLayers == 1 ? VkImageViewType.ImageCube : VkImageViewType.ImageCubeArray; imageViewCI.subresourceRange.layerCount *= 6; } else if (tex.Depth == 1) { imageViewCI.viewType = description.ArrayLayers == 1 ? VkImageViewType.Image2D : VkImageViewType.Image2DArray; } else { imageViewCI.viewType = VkImageViewType.Image3D; } vkCreateImageView(_gd.Device, ref imageViewCI, null, out _imageView); }
public VkCommandList(VkGraphicsDevice gd, ref CommandListDescription description) : base(ref description) { _gd = gd; VkCommandPoolCreateInfo poolCI = VkCommandPoolCreateInfo.New(); poolCI.queueFamilyIndex = gd.GraphicsQueueIndex; VkResult result = vkCreateCommandPool(_gd.Device, ref poolCI, null, out _pool); CheckResult(result); VkCommandBufferAllocateInfo cbAI = VkCommandBufferAllocateInfo.New(); cbAI.commandPool = _pool; cbAI.commandBufferCount = 1; cbAI.level = VkCommandBufferLevel.Primary; result = vkAllocateCommandBuffers(gd.Device, ref cbAI, out _cb); CheckResult(result); }
internal VkTexture( VkGraphicsDevice gd, uint width, uint height, uint mipLevels, uint arrayLayers, VkFormat vkFormat, TextureUsage usage, VkImage existingImage) { _gd = gd; MipLevels = mipLevels; Width = width; Height = height; Depth = 1; VkFormat = vkFormat; Format = VkFormats.VkToVdPixelFormat(VkFormat); ArrayLayers = arrayLayers; Usage = usage; _image = existingImage; }
public VkResourceLayout(VkGraphicsDevice gd, ref ResourceLayoutDescription description) : base(ref description) { _gd = gd; VkDescriptorSetLayoutCreateInfo dslCI = VkDescriptorSetLayoutCreateInfo.New(); ResourceLayoutElementDescription[] elements = description.Elements; _descriptorTypes = new VkDescriptorType[elements.Length]; VkDescriptorSetLayoutBinding *bindings = stackalloc VkDescriptorSetLayoutBinding[elements.Length]; uint uniformBufferCount = 0; uint sampledImageCount = 0; uint samplerCount = 0; uint storageBufferCount = 0; uint storageImageCount = 0; for (uint i = 0; i < elements.Length; i++) { bindings[i].binding = i; bindings[i].descriptorCount = 1; VkDescriptorType descriptorType = VkFormats.VdToVkDescriptorType(elements[i].Kind, elements[i].Options); bindings[i].descriptorType = descriptorType; bindings[i].stageFlags = VkFormats.VdToVkShaderStages(elements[i].Stages); if ((elements[i].Options & ResourceLayoutElementOptions.DynamicBinding) != 0) { DynamicBufferCount += 1; } _descriptorTypes[i] = descriptorType; switch (descriptorType) { case VkDescriptorType.Sampler: samplerCount += 1; break; case VkDescriptorType.SampledImage: sampledImageCount += 1; break; case VkDescriptorType.StorageImage: storageImageCount += 1; break; case VkDescriptorType.UniformBuffer: uniformBufferCount += 1; break; case VkDescriptorType.StorageBuffer: storageBufferCount += 1; break; } } DescriptorResourceCounts = new DescriptorResourceCounts( uniformBufferCount, sampledImageCount, samplerCount, storageBufferCount, storageImageCount); dslCI.bindingCount = (uint)elements.Length; dslCI.pBindings = bindings; VkResult result = vkCreateDescriptorSetLayout(_gd.Device, ref dslCI, null, out _dsl); CheckResult(result); }
public VkPipeline(VkGraphicsDevice gd, ref GraphicsPipelineDescription description) : base(ref description) { _gd = gd; IsComputePipeline = false; RefCount = new ResourceRefCount(DisposeCore); VkGraphicsPipelineCreateInfo pipelineCI = VkGraphicsPipelineCreateInfo.New(); // Blend State VkPipelineColorBlendStateCreateInfo blendStateCI = VkPipelineColorBlendStateCreateInfo.New(); int attachmentsCount = description.BlendState.AttachmentStates.Length; VkPipelineColorBlendAttachmentState *attachmentsPtr = stackalloc VkPipelineColorBlendAttachmentState[attachmentsCount]; for (int i = 0; i < attachmentsCount; i++) { BlendAttachmentDescription vdDesc = description.BlendState.AttachmentStates[i]; VkPipelineColorBlendAttachmentState attachmentState = new VkPipelineColorBlendAttachmentState(); attachmentState.srcColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceColorFactor); attachmentState.dstColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationColorFactor); attachmentState.colorBlendOp = VkFormats.VdToVkBlendOp(vdDesc.ColorFunction); attachmentState.srcAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceAlphaFactor); attachmentState.dstAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationAlphaFactor); attachmentState.alphaBlendOp = VkFormats.VdToVkBlendOp(vdDesc.AlphaFunction); attachmentState.blendEnable = vdDesc.BlendEnabled; attachmentState.colorWriteMask = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A; attachmentsPtr[i] = attachmentState; } blendStateCI.attachmentCount = (uint)attachmentsCount; blendStateCI.pAttachments = attachmentsPtr; RgbaFloat blendFactor = description.BlendState.BlendFactor; blendStateCI.blendConstants_0 = blendFactor.R; blendStateCI.blendConstants_1 = blendFactor.G; blendStateCI.blendConstants_2 = blendFactor.B; blendStateCI.blendConstants_3 = blendFactor.A; pipelineCI.pColorBlendState = &blendStateCI; // Rasterizer State RasterizerStateDescription rsDesc = description.RasterizerState; VkPipelineRasterizationStateCreateInfo rsCI = VkPipelineRasterizationStateCreateInfo.New(); rsCI.cullMode = VkFormats.VdToVkCullMode(rsDesc.CullMode); rsCI.polygonMode = VkFormats.VdToVkPolygonMode(rsDesc.FillMode); rsCI.depthClampEnable = !rsDesc.DepthClipEnabled; rsCI.frontFace = rsDesc.FrontFace == FrontFace.Clockwise ? VkFrontFace.Clockwise : VkFrontFace.CounterClockwise; rsCI.lineWidth = 1f; pipelineCI.pRasterizationState = &rsCI; ScissorTestEnabled = rsDesc.ScissorTestEnabled; // Dynamic State VkPipelineDynamicStateCreateInfo dynamicStateCI = VkPipelineDynamicStateCreateInfo.New(); VkDynamicState *dynamicStates = stackalloc VkDynamicState[2]; dynamicStates[0] = VkDynamicState.Viewport; dynamicStates[1] = VkDynamicState.Scissor; dynamicStateCI.dynamicStateCount = 2; dynamicStateCI.pDynamicStates = dynamicStates; pipelineCI.pDynamicState = &dynamicStateCI; // Depth Stencil State DepthStencilStateDescription vdDssDesc = description.DepthStencilState; VkPipelineDepthStencilStateCreateInfo dssCI = VkPipelineDepthStencilStateCreateInfo.New(); dssCI.depthWriteEnable = vdDssDesc.DepthWriteEnabled; dssCI.depthTestEnable = vdDssDesc.DepthTestEnabled; dssCI.depthCompareOp = VkFormats.VdToVkCompareOp(vdDssDesc.DepthComparison); dssCI.stencilTestEnable = vdDssDesc.StencilTestEnabled; dssCI.front.failOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.Fail); dssCI.front.passOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.Pass); dssCI.front.depthFailOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.DepthFail); dssCI.front.compareOp = VkFormats.VdToVkCompareOp(vdDssDesc.StencilFront.Comparison); dssCI.front.compareMask = vdDssDesc.StencilReadMask; dssCI.front.writeMask = vdDssDesc.StencilWriteMask; dssCI.front.reference = vdDssDesc.StencilReference; dssCI.back.failOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.Fail); dssCI.back.passOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.Pass); dssCI.back.depthFailOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.DepthFail); dssCI.back.compareOp = VkFormats.VdToVkCompareOp(vdDssDesc.StencilBack.Comparison); dssCI.back.compareMask = vdDssDesc.StencilReadMask; dssCI.back.writeMask = vdDssDesc.StencilWriteMask; dssCI.back.reference = vdDssDesc.StencilReference; pipelineCI.pDepthStencilState = &dssCI; // Multisample VkPipelineMultisampleStateCreateInfo multisampleCI = VkPipelineMultisampleStateCreateInfo.New(); VkSampleCountFlags vkSampleCount = VkFormats.VdToVkSampleCount(description.Outputs.SampleCount); multisampleCI.rasterizationSamples = vkSampleCount; multisampleCI.alphaToCoverageEnable = description.BlendState.AlphaToCoverageEnabled; pipelineCI.pMultisampleState = &multisampleCI; // Input Assembly VkPipelineInputAssemblyStateCreateInfo inputAssemblyCI = VkPipelineInputAssemblyStateCreateInfo.New(); inputAssemblyCI.topology = VkFormats.VdToVkPrimitiveTopology(description.PrimitiveTopology); pipelineCI.pInputAssemblyState = &inputAssemblyCI; // Vertex Input State VkPipelineVertexInputStateCreateInfo vertexInputCI = VkPipelineVertexInputStateCreateInfo.New(); VertexLayoutDescription[] inputDescriptions = description.ShaderSet.VertexLayouts; uint bindingCount = (uint)inputDescriptions.Length; uint attributeCount = 0; for (int i = 0; i < inputDescriptions.Length; i++) { attributeCount += (uint)inputDescriptions[i].Elements.Length; } VkVertexInputBindingDescription * bindingDescs = stackalloc VkVertexInputBindingDescription[(int)bindingCount]; VkVertexInputAttributeDescription *attributeDescs = stackalloc VkVertexInputAttributeDescription[(int)attributeCount]; int targetIndex = 0; int targetLocation = 0; for (int binding = 0; binding < inputDescriptions.Length; binding++) { VertexLayoutDescription inputDesc = inputDescriptions[binding]; bindingDescs[binding] = new VkVertexInputBindingDescription() { binding = (uint)binding, inputRate = (inputDesc.InstanceStepRate != 0) ? VkVertexInputRate.Instance : VkVertexInputRate.Vertex, stride = inputDesc.Stride }; uint currentOffset = 0; for (int location = 0; location < inputDesc.Elements.Length; location++) { VertexElementDescription inputElement = inputDesc.Elements[location]; attributeDescs[targetIndex] = new VkVertexInputAttributeDescription() { format = VkFormats.VdToVkVertexElementFormat(inputElement.Format), binding = (uint)binding, location = (uint)(targetLocation + location), offset = inputElement.Offset != 0 ? inputElement.Offset : currentOffset }; targetIndex += 1; currentOffset += FormatHelpers.GetSizeInBytes(inputElement.Format); } targetLocation += inputDesc.Elements.Length; } vertexInputCI.vertexBindingDescriptionCount = bindingCount; vertexInputCI.pVertexBindingDescriptions = bindingDescs; vertexInputCI.vertexAttributeDescriptionCount = attributeCount; vertexInputCI.pVertexAttributeDescriptions = attributeDescs; pipelineCI.pVertexInputState = &vertexInputCI; // Shader Stage VkSpecializationInfo specializationInfo; SpecializationConstant[] specDescs = description.ShaderSet.Specializations; if (specDescs != null) { uint specDataSize = 0; foreach (SpecializationConstant spec in specDescs) { specDataSize += VkFormats.GetSpecializationConstantSize(spec.Type); } byte *fullSpecData = stackalloc byte[(int)specDataSize]; int specializationCount = specDescs.Length; VkSpecializationMapEntry *mapEntries = stackalloc VkSpecializationMapEntry[specializationCount]; uint specOffset = 0; for (int i = 0; i < specializationCount; i++) { ulong data = specDescs[i].Data; byte *srcData = (byte *)&data; uint dataSize = VkFormats.GetSpecializationConstantSize(specDescs[i].Type); Unsafe.CopyBlock(fullSpecData + specOffset, srcData, dataSize); mapEntries[i].constantID = specDescs[i].ID; mapEntries[i].offset = specOffset; mapEntries[i].size = (UIntPtr)dataSize; specOffset += dataSize; } specializationInfo.dataSize = (UIntPtr)specDataSize; specializationInfo.pData = fullSpecData; specializationInfo.mapEntryCount = (uint)specializationCount; specializationInfo.pMapEntries = mapEntries; } Shader[] shaders = description.ShaderSet.Shaders; StackList <VkPipelineShaderStageCreateInfo> stages = new StackList <VkPipelineShaderStageCreateInfo>(); foreach (Shader shader in shaders) { VkShader vkShader = Util.AssertSubtype <Shader, VkShader>(shader); VkPipelineShaderStageCreateInfo stageCI = VkPipelineShaderStageCreateInfo.New(); stageCI.module = vkShader.ShaderModule; stageCI.stage = VkFormats.VdToVkShaderStages(shader.Stage); // stageCI.pName = CommonStrings.main; // Meh stageCI.pName = new FixedUtf8String(shader.EntryPoint); // TODO: DONT ALLOCATE HERE stageCI.pSpecializationInfo = &specializationInfo; stages.Add(stageCI); } pipelineCI.stageCount = stages.Count; pipelineCI.pStages = (VkPipelineShaderStageCreateInfo *)stages.Data; // ViewportState VkPipelineViewportStateCreateInfo viewportStateCI = VkPipelineViewportStateCreateInfo.New(); viewportStateCI.viewportCount = 1; viewportStateCI.scissorCount = 1; pipelineCI.pViewportState = &viewportStateCI; // Pipeline Layout ResourceLayout[] resourceLayouts = description.ResourceLayouts; VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New(); pipelineLayoutCI.setLayoutCount = (uint)resourceLayouts.Length; VkDescriptorSetLayout *dsls = stackalloc VkDescriptorSetLayout[resourceLayouts.Length]; for (int i = 0; i < resourceLayouts.Length; i++) { dsls[i] = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(resourceLayouts[i]).DescriptorSetLayout; } pipelineLayoutCI.pSetLayouts = dsls; vkCreatePipelineLayout(_gd.Device, ref pipelineLayoutCI, null, out _pipelineLayout); pipelineCI.layout = _pipelineLayout; // Create fake RenderPass for compatibility. VkRenderPassCreateInfo renderPassCI = VkRenderPassCreateInfo.New(); OutputDescription outputDesc = description.Outputs; StackList <VkAttachmentDescription, Size512Bytes> attachments = new StackList <VkAttachmentDescription, Size512Bytes>(); // TODO: A huge portion of this next part is duplicated in VkFramebuffer.cs. StackList <VkAttachmentDescription> colorAttachmentDescs = new StackList <VkAttachmentDescription>(); StackList <VkAttachmentReference> colorAttachmentRefs = new StackList <VkAttachmentReference>(); for (uint i = 0; i < outputDesc.ColorAttachments.Length; i++) { colorAttachmentDescs[i].format = VkFormats.VdToVkPixelFormat(outputDesc.ColorAttachments[i].Format); colorAttachmentDescs[i].samples = vkSampleCount; colorAttachmentDescs[i].loadOp = VkAttachmentLoadOp.DontCare; colorAttachmentDescs[i].storeOp = VkAttachmentStoreOp.Store; colorAttachmentDescs[i].stencilLoadOp = VkAttachmentLoadOp.DontCare; colorAttachmentDescs[i].stencilStoreOp = VkAttachmentStoreOp.DontCare; colorAttachmentDescs[i].initialLayout = VkImageLayout.Undefined; colorAttachmentDescs[i].finalLayout = VkImageLayout.ShaderReadOnlyOptimal; attachments.Add(colorAttachmentDescs[i]); colorAttachmentRefs[i].attachment = i; colorAttachmentRefs[i].layout = VkImageLayout.ColorAttachmentOptimal; } VkAttachmentDescription depthAttachmentDesc = new VkAttachmentDescription(); VkAttachmentReference depthAttachmentRef = new VkAttachmentReference(); if (outputDesc.DepthAttachment != null) { PixelFormat depthFormat = outputDesc.DepthAttachment.Value.Format; bool hasStencil = FormatHelpers.IsStencilFormat(depthFormat); depthAttachmentDesc.format = VkFormats.VdToVkPixelFormat(outputDesc.DepthAttachment.Value.Format, toDepthFormat: true); depthAttachmentDesc.samples = vkSampleCount; depthAttachmentDesc.loadOp = VkAttachmentLoadOp.DontCare; depthAttachmentDesc.storeOp = VkAttachmentStoreOp.Store; depthAttachmentDesc.stencilLoadOp = VkAttachmentLoadOp.DontCare; depthAttachmentDesc.stencilStoreOp = hasStencil ? VkAttachmentStoreOp.Store : VkAttachmentStoreOp.DontCare; depthAttachmentDesc.initialLayout = VkImageLayout.Undefined; depthAttachmentDesc.finalLayout = VkImageLayout.DepthStencilAttachmentOptimal; depthAttachmentRef.attachment = (uint)outputDesc.ColorAttachments.Length; depthAttachmentRef.layout = VkImageLayout.DepthStencilAttachmentOptimal; } VkSubpassDescription subpass = new VkSubpassDescription(); subpass.pipelineBindPoint = VkPipelineBindPoint.Graphics; subpass.colorAttachmentCount = (uint)outputDesc.ColorAttachments.Length; subpass.pColorAttachments = (VkAttachmentReference *)colorAttachmentRefs.Data; for (int i = 0; i < colorAttachmentDescs.Count; i++) { attachments.Add(colorAttachmentDescs[i]); } if (outputDesc.DepthAttachment != null) { subpass.pDepthStencilAttachment = &depthAttachmentRef; attachments.Add(depthAttachmentDesc); } VkSubpassDependency subpassDependency = new VkSubpassDependency(); subpassDependency.srcSubpass = SubpassExternal; subpassDependency.srcStageMask = VkPipelineStageFlags.ColorAttachmentOutput; subpassDependency.dstStageMask = VkPipelineStageFlags.ColorAttachmentOutput; subpassDependency.dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite; renderPassCI.attachmentCount = attachments.Count; renderPassCI.pAttachments = (VkAttachmentDescription *)attachments.Data; renderPassCI.subpassCount = 1; renderPassCI.pSubpasses = &subpass; renderPassCI.dependencyCount = 1; renderPassCI.pDependencies = &subpassDependency; VkResult creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPass); CheckResult(creationResult); pipelineCI.renderPass = _renderPass; VkResult result = vkCreateGraphicsPipelines(_gd.Device, VkPipelineCache.Null, 1, ref pipelineCI, null, out _devicePipeline); CheckResult(result); ResourceSetCount = (uint)description.ResourceLayouts.Length; DynamicOffsetsCount = 0; foreach (VkResourceLayout layout in description.ResourceLayouts) { DynamicOffsetsCount += layout.DynamicBufferCount; } }
public VkPipeline(VkGraphicsDevice gd, ref ComputePipelineDescription description) : base(ref description) { _gd = gd; IsComputePipeline = true; RefCount = new ResourceRefCount(DisposeCore); VkComputePipelineCreateInfo pipelineCI = VkComputePipelineCreateInfo.New(); // Pipeline Layout ResourceLayout[] resourceLayouts = description.ResourceLayouts; VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New(); pipelineLayoutCI.setLayoutCount = (uint)resourceLayouts.Length; VkDescriptorSetLayout *dsls = stackalloc VkDescriptorSetLayout[resourceLayouts.Length]; for (int i = 0; i < resourceLayouts.Length; i++) { dsls[i] = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(resourceLayouts[i]).DescriptorSetLayout; } pipelineLayoutCI.pSetLayouts = dsls; vkCreatePipelineLayout(_gd.Device, ref pipelineLayoutCI, null, out _pipelineLayout); pipelineCI.layout = _pipelineLayout; // Shader Stage VkSpecializationInfo specializationInfo; SpecializationConstant[] specDescs = description.Specializations; if (specDescs != null) { uint specDataSize = 0; foreach (SpecializationConstant spec in specDescs) { specDataSize += VkFormats.GetSpecializationConstantSize(spec.Type); } byte *fullSpecData = stackalloc byte[(int)specDataSize]; int specializationCount = specDescs.Length; VkSpecializationMapEntry *mapEntries = stackalloc VkSpecializationMapEntry[specializationCount]; uint specOffset = 0; for (int i = 0; i < specializationCount; i++) { ulong data = specDescs[i].Data; byte *srcData = (byte *)&data; uint dataSize = VkFormats.GetSpecializationConstantSize(specDescs[i].Type); Unsafe.CopyBlock(fullSpecData + specOffset, srcData, dataSize); mapEntries[i].constantID = specDescs[i].ID; mapEntries[i].offset = specOffset; mapEntries[i].size = (UIntPtr)dataSize; specOffset += dataSize; } specializationInfo.dataSize = (UIntPtr)specDataSize; specializationInfo.pData = fullSpecData; specializationInfo.mapEntryCount = (uint)specializationCount; specializationInfo.pMapEntries = mapEntries; } Shader shader = description.ComputeShader; VkShader vkShader = Util.AssertSubtype <Shader, VkShader>(shader); VkPipelineShaderStageCreateInfo stageCI = VkPipelineShaderStageCreateInfo.New(); stageCI.module = vkShader.ShaderModule; stageCI.stage = VkFormats.VdToVkShaderStages(shader.Stage); stageCI.pName = CommonStrings.main; // Meh stageCI.pSpecializationInfo = &specializationInfo; pipelineCI.stage = stageCI; VkResult result = vkCreateComputePipelines( _gd.Device, VkPipelineCache.Null, 1, ref pipelineCI, null, out _devicePipeline); CheckResult(result); ResourceSetCount = (uint)description.ResourceLayouts.Length; DynamicOffsetsCount = 0; foreach (VkResourceLayout layout in description.ResourceLayouts) { DynamicOffsetsCount += layout.DynamicBufferCount; } }
public VkFramebuffer(VkGraphicsDevice gd, ref FramebufferDescription description, bool isPresented) : base(description.DepthTarget, description.ColorTargets) { _gd = gd; VkRenderPassCreateInfo renderPassCI = VkRenderPassCreateInfo.New(); StackList <VkAttachmentDescription> attachments = new StackList <VkAttachmentDescription>(); uint colorAttachmentCount = (uint)ColorTargets.Count; StackList <VkAttachmentReference> colorAttachmentRefs = new StackList <VkAttachmentReference>(); for (int i = 0; i < colorAttachmentCount; i++) { VkTexture vkColorTex = Util.AssertSubtype <Texture, VkTexture>(ColorTargets[i].Target); VkAttachmentDescription colorAttachmentDesc = new VkAttachmentDescription(); colorAttachmentDesc.format = vkColorTex.VkFormat; colorAttachmentDesc.samples = vkColorTex.VkSampleCount; colorAttachmentDesc.loadOp = VkAttachmentLoadOp.DontCare; colorAttachmentDesc.storeOp = VkAttachmentStoreOp.Store; colorAttachmentDesc.stencilLoadOp = VkAttachmentLoadOp.DontCare; colorAttachmentDesc.stencilStoreOp = VkAttachmentStoreOp.DontCare; colorAttachmentDesc.initialLayout = VkImageLayout.Undefined; colorAttachmentDesc.finalLayout = VkImageLayout.ColorAttachmentOptimal; attachments.Add(colorAttachmentDesc); VkAttachmentReference colorAttachmentRef = new VkAttachmentReference(); colorAttachmentRef.attachment = (uint)i; colorAttachmentRef.layout = VkImageLayout.ColorAttachmentOptimal; colorAttachmentRefs.Add(colorAttachmentRef); } VkAttachmentDescription depthAttachmentDesc = new VkAttachmentDescription(); VkAttachmentReference depthAttachmentRef = new VkAttachmentReference(); if (DepthTarget != null) { VkTexture vkDepthTex = Util.AssertSubtype <Texture, VkTexture>(DepthTarget.Value.Target); bool hasStencil = FormatHelpers.IsStencilFormat(vkDepthTex.Format); depthAttachmentDesc.format = vkDepthTex.VkFormat; depthAttachmentDesc.samples = vkDepthTex.VkSampleCount; depthAttachmentDesc.loadOp = VkAttachmentLoadOp.DontCare; depthAttachmentDesc.storeOp = VkAttachmentStoreOp.Store; depthAttachmentDesc.stencilLoadOp = VkAttachmentLoadOp.DontCare; depthAttachmentDesc.stencilStoreOp = hasStencil ? VkAttachmentStoreOp.Store : VkAttachmentStoreOp.DontCare; depthAttachmentDesc.initialLayout = VkImageLayout.Undefined; depthAttachmentDesc.finalLayout = VkImageLayout.DepthStencilAttachmentOptimal; depthAttachmentRef.attachment = (uint)description.ColorTargets.Length; depthAttachmentRef.layout = VkImageLayout.DepthStencilAttachmentOptimal; } VkSubpassDescription subpass = new VkSubpassDescription(); subpass.pipelineBindPoint = VkPipelineBindPoint.Graphics; if (ColorTargets.Count > 0) { subpass.colorAttachmentCount = colorAttachmentCount; subpass.pColorAttachments = (VkAttachmentReference *)colorAttachmentRefs.Data; } if (DepthTarget != null) { subpass.pDepthStencilAttachment = &depthAttachmentRef; attachments.Add(depthAttachmentDesc); } VkSubpassDependency subpassDependency = new VkSubpassDependency(); subpassDependency.srcSubpass = SubpassExternal; subpassDependency.srcStageMask = VkPipelineStageFlags.ColorAttachmentOutput; subpassDependency.dstStageMask = VkPipelineStageFlags.ColorAttachmentOutput; subpassDependency.dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite; if (DepthTarget != null) { subpassDependency.dstAccessMask |= VkAccessFlags.DepthStencilAttachmentRead | VkAccessFlags.DepthStencilAttachmentWrite; } renderPassCI.attachmentCount = attachments.Count; renderPassCI.pAttachments = (VkAttachmentDescription *)attachments.Data; renderPassCI.subpassCount = 1; renderPassCI.pSubpasses = &subpass; renderPassCI.dependencyCount = 1; renderPassCI.pDependencies = &subpassDependency; VkResult creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPassNoClear); CheckResult(creationResult); for (int i = 0; i < colorAttachmentCount; i++) { attachments[i].loadOp = VkAttachmentLoadOp.Load; attachments[i].initialLayout = VkImageLayout.ColorAttachmentOptimal; } if (DepthTarget != null) { attachments[attachments.Count - 1].loadOp = VkAttachmentLoadOp.Load; attachments[attachments.Count - 1].initialLayout = VkImageLayout.DepthStencilAttachmentOptimal; bool hasStencil = FormatHelpers.IsStencilFormat(DepthTarget.Value.Target.Format); if (hasStencil) { attachments[attachments.Count - 1].stencilLoadOp = VkAttachmentLoadOp.Load; } } creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPassNoClearLoad); CheckResult(creationResult); // Load version if (DepthTarget != null) { attachments[attachments.Count - 1].loadOp = VkAttachmentLoadOp.Clear; attachments[attachments.Count - 1].initialLayout = VkImageLayout.Undefined; bool hasStencil = FormatHelpers.IsStencilFormat(DepthTarget.Value.Target.Format); if (hasStencil) { attachments[attachments.Count - 1].stencilLoadOp = VkAttachmentLoadOp.Clear; } } for (int i = 0; i < colorAttachmentCount; i++) { attachments[i].loadOp = VkAttachmentLoadOp.Clear; attachments[i].initialLayout = VkImageLayout.Undefined; } creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPassClear); CheckResult(creationResult); VkFramebufferCreateInfo fbCI = VkFramebufferCreateInfo.New(); uint fbAttachmentsCount = (uint)description.ColorTargets.Length; if (description.DepthTarget != null) { fbAttachmentsCount += 1; } VkImageView *fbAttachments = stackalloc VkImageView[(int)fbAttachmentsCount]; for (int i = 0; i < colorAttachmentCount; i++) { VkTexture vkColorTarget = Util.AssertSubtype <Texture, VkTexture>(description.ColorTargets[i].Target); VkImageViewCreateInfo imageViewCI = VkImageViewCreateInfo.New(); imageViewCI.image = vkColorTarget.OptimalDeviceImage; imageViewCI.format = vkColorTarget.VkFormat; imageViewCI.viewType = VkImageViewType.Image2D; imageViewCI.subresourceRange = new VkImageSubresourceRange( VkImageAspectFlags.Color, description.ColorTargets[i].MipLevel, 1, description.ColorTargets[i].ArrayLayer, 1); VkImageView *dest = (fbAttachments + i); VkResult result = vkCreateImageView(_gd.Device, ref imageViewCI, null, dest); CheckResult(result); _attachmentViews.Add(*dest); } // Depth if (description.DepthTarget != null) { VkTexture vkDepthTarget = Util.AssertSubtype <Texture, VkTexture>(description.DepthTarget.Value.Target); bool hasStencil = FormatHelpers.IsStencilFormat(vkDepthTarget.Format); VkImageViewCreateInfo depthViewCI = VkImageViewCreateInfo.New(); depthViewCI.image = vkDepthTarget.OptimalDeviceImage; depthViewCI.format = vkDepthTarget.VkFormat; depthViewCI.viewType = description.DepthTarget.Value.Target.ArrayLayers == 1 ? VkImageViewType.Image2D : VkImageViewType.Image2DArray; depthViewCI.subresourceRange = new VkImageSubresourceRange( hasStencil ? VkImageAspectFlags.Depth | VkImageAspectFlags.Stencil : VkImageAspectFlags.Depth, description.DepthTarget.Value.MipLevel, 1, description.DepthTarget.Value.ArrayLayer, 1); VkImageView *dest = (fbAttachments + (fbAttachmentsCount - 1)); VkResult result = vkCreateImageView(_gd.Device, ref depthViewCI, null, dest); CheckResult(result); _attachmentViews.Add(*dest); } Texture dimTex; uint mipLevel; if (ColorTargets.Count > 0) { dimTex = ColorTargets[0].Target; mipLevel = ColorTargets[0].MipLevel; } else { Debug.Assert(DepthTarget != null); dimTex = DepthTarget.Value.Target; mipLevel = DepthTarget.Value.MipLevel; } Util.GetMipDimensions( dimTex, mipLevel, out uint mipWidth, out uint mipHeight, out _); fbCI.width = mipWidth; fbCI.height = mipHeight; fbCI.attachmentCount = fbAttachmentsCount; fbCI.pAttachments = fbAttachments; fbCI.layers = 1; fbCI.renderPass = _renderPassNoClear; creationResult = vkCreateFramebuffer(_gd.Device, ref fbCI, null, out _deviceFramebuffer); CheckResult(creationResult); if (DepthTarget != null) { AttachmentCount += 1; } AttachmentCount += (uint)ColorTargets.Count; }
public VkDescriptorPoolManager(VkGraphicsDevice gd) { _gd = gd; _pools.Add(CreateNewPool()); }
public VkResourceFactory(VkGraphicsDevice vkGraphicsDevice) { _gd = vkGraphicsDevice; _device = vkGraphicsDevice.Device; }
public VkResourceSet(VkGraphicsDevice gd, ref ResourceSetDescription description) : base(ref description) { _gd = gd; RefCount = new ResourceRefCount(DisposeCore); VkResourceLayout vkLayout = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(description.Layout); VkDescriptorSetLayout dsl = vkLayout.DescriptorSetLayout; _descriptorCounts = vkLayout.DescriptorResourceCounts; _descriptorAllocationToken = _gd.DescriptorPoolManager.Allocate(_descriptorCounts, dsl); BindableResource[] boundResources = description.BoundResources; uint descriptorWriteCount = (uint)boundResources.Length; VkWriteDescriptorSet * descriptorWrites = stackalloc VkWriteDescriptorSet[(int)descriptorWriteCount]; VkDescriptorBufferInfo *bufferInfos = stackalloc VkDescriptorBufferInfo[(int)descriptorWriteCount]; VkDescriptorImageInfo * imageInfos = stackalloc VkDescriptorImageInfo[(int)descriptorWriteCount]; for (int i = 0; i < descriptorWriteCount; i++) { VkDescriptorType type = vkLayout.DescriptorTypes[i]; descriptorWrites[i].sType = VkStructureType.WriteDescriptorSet; descriptorWrites[i].descriptorCount = 1; descriptorWrites[i].descriptorType = type; descriptorWrites[i].dstBinding = (uint)i; descriptorWrites[i].dstSet = _descriptorAllocationToken.Set; if (type == VkDescriptorType.UniformBuffer || type == VkDescriptorType.UniformBufferDynamic || type == VkDescriptorType.StorageBuffer || type == VkDescriptorType.StorageBufferDynamic) { DeviceBufferRange range = Util.GetBufferRange(boundResources[i], 0); VkBuffer rangedVkBuffer = Util.AssertSubtype <DeviceBuffer, VkBuffer>(range.Buffer); bufferInfos[i].buffer = rangedVkBuffer.DeviceBuffer; bufferInfos[i].offset = range.Offset; bufferInfos[i].range = range.SizeInBytes; descriptorWrites[i].pBufferInfo = &bufferInfos[i]; _refCounts.Add(rangedVkBuffer.RefCount); } else if (type == VkDescriptorType.SampledImage) { TextureView texView = Util.GetTextureView(_gd, boundResources[i]); VkTextureView vkTexView = Util.AssertSubtype <TextureView, VkTextureView>(texView); imageInfos[i].imageView = vkTexView.ImageView; imageInfos[i].imageLayout = VkImageLayout.ShaderReadOnlyOptimal; descriptorWrites[i].pImageInfo = &imageInfos[i]; _sampledTextures.Add(Util.AssertSubtype <Texture, VkTexture>(texView.Target)); _refCounts.Add(vkTexView.RefCount); } else if (type == VkDescriptorType.StorageImage) { TextureView texView = Util.GetTextureView(_gd, boundResources[i]); VkTextureView vkTexView = Util.AssertSubtype <TextureView, VkTextureView>(texView); imageInfos[i].imageView = vkTexView.ImageView; imageInfos[i].imageLayout = VkImageLayout.General; descriptorWrites[i].pImageInfo = &imageInfos[i]; _storageImages.Add(Util.AssertSubtype <Texture, VkTexture>(texView.Target)); _refCounts.Add(vkTexView.RefCount); } else if (type == VkDescriptorType.Sampler) { VkSampler sampler = Util.AssertSubtype <BindableResource, VkSampler>(boundResources[i]); imageInfos[i].sampler = sampler.DeviceSampler; descriptorWrites[i].pImageInfo = &imageInfos[i]; _refCounts.Add(sampler.RefCount); } } vkUpdateDescriptorSets(_gd.Device, descriptorWriteCount, descriptorWrites, 0, null); }
internal VkTexture(VkGraphicsDevice gd, ref TextureDescription description) { _gd = gd; _width = description.Width; _height = description.Height; _depth = description.Depth; MipLevels = description.MipLevels; ArrayLayers = description.ArrayLayers; bool isCubemap = ((description.Usage) & TextureUsage.Cubemap) == TextureUsage.Cubemap; _actualImageArrayLayers = isCubemap ? 6 * ArrayLayers : ArrayLayers; _format = description.Format; Usage = description.Usage; Type = description.Type; SampleCount = description.SampleCount; VkSampleCount = VkFormats.VdToVkSampleCount(SampleCount); VkFormat = VkFormats.VdToVkPixelFormat(Format, (description.Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil); bool isStaging = (Usage & TextureUsage.Staging) == TextureUsage.Staging; if (!isStaging) { VkImageCreateInfo imageCI = VkImageCreateInfo.New(); imageCI.mipLevels = MipLevels; imageCI.arrayLayers = _actualImageArrayLayers; imageCI.imageType = VkFormats.VdToVkTextureType(Type); imageCI.extent.width = Width; imageCI.extent.height = Height; imageCI.extent.depth = Depth; imageCI.initialLayout = VkImageLayout.Preinitialized; imageCI.usage = VkFormats.VdToVkTextureUsage(Usage); imageCI.tiling = isStaging ? VkImageTiling.Linear : VkImageTiling.Optimal; imageCI.format = VkFormat; imageCI.samples = VkSampleCount; if (isCubemap) { imageCI.flags = VkImageCreateFlags.CubeCompatible; } uint subresourceCount = MipLevels * _actualImageArrayLayers * Depth; VkResult result = vkCreateImage(gd.Device, ref imageCI, null, out _optimalImage); CheckResult(result); vkGetImageMemoryRequirements(gd.Device, _optimalImage, out VkMemoryRequirements memoryRequirements); VkMemoryBlock memoryToken = gd.MemoryManager.Allocate( gd.PhysicalDeviceMemProperties, memoryRequirements.memoryTypeBits, VkMemoryPropertyFlags.DeviceLocal, false, memoryRequirements.size, memoryRequirements.alignment); _memoryBlock = memoryToken; result = vkBindImageMemory(gd.Device, _optimalImage, _memoryBlock.DeviceMemory, _memoryBlock.Offset); CheckResult(result); _imageLayouts = new VkImageLayout[subresourceCount]; for (int i = 0; i < _imageLayouts.Length; i++) { _imageLayouts[i] = VkImageLayout.Preinitialized; } } else // isStaging { uint depthPitch = FormatHelpers.GetDepthPitch( FormatHelpers.GetRowPitch(Width, Format), Height, Format); uint stagingSize = depthPitch * Depth; for (uint level = 1; level < MipLevels; level++) { Util.GetMipDimensions(this, level, out uint mipWidth, out uint mipHeight, out uint mipDepth); depthPitch = FormatHelpers.GetDepthPitch( FormatHelpers.GetRowPitch(mipWidth, Format), mipHeight, Format); stagingSize += depthPitch * mipDepth; } stagingSize *= ArrayLayers; VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New(); bufferCI.usage = VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst; bufferCI.size = stagingSize; VkResult result = vkCreateBuffer(_gd.Device, ref bufferCI, null, out _stagingBuffer); CheckResult(result); vkGetBufferMemoryRequirements(_gd.Device, _stagingBuffer, out VkMemoryRequirements bufferMemReqs); _memoryBlock = _gd.MemoryManager.Allocate( _gd.PhysicalDeviceMemProperties, bufferMemReqs.memoryTypeBits, VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent, true, bufferMemReqs.size, bufferMemReqs.alignment); result = vkBindBufferMemory(_gd.Device, _stagingBuffer, _memoryBlock.DeviceMemory, _memoryBlock.Offset); CheckResult(result); } ClearIfRenderTarget(); }
public VkBuffer(VkGraphicsDevice gd, uint sizeInBytes, BufferUsage usage, string callerMember = null) { _gd = gd; SizeInBytes = sizeInBytes; Usage = usage; VkBufferUsageFlags vkUsage = VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst; if ((usage & BufferUsage.VertexBuffer) == BufferUsage.VertexBuffer) { vkUsage |= VkBufferUsageFlags.VertexBuffer; } if ((usage & BufferUsage.IndexBuffer) == BufferUsage.IndexBuffer) { vkUsage |= VkBufferUsageFlags.IndexBuffer; } if ((usage & BufferUsage.UniformBuffer) == BufferUsage.UniformBuffer) { vkUsage |= VkBufferUsageFlags.UniformBuffer; } if ((usage & BufferUsage.StructuredBufferReadWrite) == BufferUsage.StructuredBufferReadWrite || (usage & BufferUsage.StructuredBufferReadOnly) == BufferUsage.StructuredBufferReadOnly) { vkUsage |= VkBufferUsageFlags.StorageBuffer; } if ((usage & BufferUsage.IndirectBuffer) == BufferUsage.IndirectBuffer) { vkUsage |= VkBufferUsageFlags.IndirectBuffer; } VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New(); bufferCI.size = sizeInBytes; bufferCI.usage = vkUsage; VkResult result = vkCreateBuffer(gd.Device, ref bufferCI, null, out _deviceBuffer); CheckResult(result); bool prefersDedicatedAllocation; if (_gd.GetBufferMemoryRequirements2 != null) { VkBufferMemoryRequirementsInfo2KHR memReqInfo2 = VkBufferMemoryRequirementsInfo2KHR.New(); memReqInfo2.buffer = _deviceBuffer; VkMemoryRequirements2KHR memReqs2 = VkMemoryRequirements2KHR.New(); VkMemoryDedicatedRequirementsKHR dedicatedReqs = VkMemoryDedicatedRequirementsKHR.New(); memReqs2.pNext = &dedicatedReqs; _gd.GetBufferMemoryRequirements2(_gd.Device, &memReqInfo2, &memReqs2); _bufferMemoryRequirements = memReqs2.memoryRequirements; prefersDedicatedAllocation = dedicatedReqs.prefersDedicatedAllocation || dedicatedReqs.requiresDedicatedAllocation; } else { vkGetBufferMemoryRequirements(gd.Device, _deviceBuffer, out _bufferMemoryRequirements); prefersDedicatedAllocation = false; } bool hostVisible = (usage & BufferUsage.Dynamic) == BufferUsage.Dynamic || (usage & BufferUsage.Staging) == BufferUsage.Staging; VkMemoryPropertyFlags memoryPropertyFlags = hostVisible ? VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent : VkMemoryPropertyFlags.DeviceLocal; VkMemoryBlock memoryToken = gd.MemoryManager.Allocate( gd.PhysicalDeviceMemProperties, _bufferMemoryRequirements.memoryTypeBits, memoryPropertyFlags, hostVisible, _bufferMemoryRequirements.size, _bufferMemoryRequirements.alignment, prefersDedicatedAllocation, VkImage.Null, _deviceBuffer); _memory = memoryToken; result = vkBindBufferMemory(gd.Device, _deviceBuffer, _memory.DeviceMemory, _memory.Offset); CheckResult(result); RefCount = new ResourceRefCount(DisposeCore); }