private void Vkctrl_VulkanClosing(object sender, SharpVulkanWpf.VulkanEventArgs args) { // 本クラスで作ったVulkanの各リソースを破棄する. var dev = args.Device; VulkanAPI.vkDestroyImage(dev, m_image); m_image = null; VulkanAPI.vkDestroyImageView(dev, m_imageView); m_imageView = null; VulkanAPI.vkFreeMemory(dev, m_imageMemory); m_imageMemory = null; VulkanAPI.vkDestroySampler(dev, m_imageSampler); m_imageSampler = null; VulkanAPI.vkDestroyPipeline(dev, m_graphicsPipeline); m_graphicsPipeline = null; VulkanAPI.vkDestroyPipelineLayout(dev, m_pipelineLayout); m_pipelineLayout = null; m_shaderStages.Select(x => x.module).ToList().ForEach(x => VulkanAPI.vkDestroyShaderModule(dev, x)); VulkanAPI.vkDestroyBuffer(dev, m_vertexBuffer); m_vertexBuffer = null; VulkanAPI.vkFreeMemory(dev, m_vertexBufferMemory); m_vertexBufferMemory = null; VulkanAPI.vkDestroyBuffer(dev, m_uniformBuffer); m_uniformBuffer = null; VulkanAPI.vkFreeMemory(dev, m_uniformBufferMemory); m_uniformBufferMemory = null; VulkanAPI.vkFreeDescriptorSets(dev, m_descriptorPool, new[] { m_descriptorSet }); VulkanAPI.vkDestroyDescriptorSetLayout(dev, m_descriptorSetLayout); m_descriptorSetLayout = null; VulkanAPI.vkDestroyDescriptorPool(dev, m_descriptorPool); m_descriptorPool = null; VulkanAPI.vkFreeCommandBuffers(dev, m_commandPool, m_commandBuffers); VulkanAPI.vkDestroyCommandPool(dev, m_commandPool); m_commandBuffers = null; m_commandPool = null; }
public void Destroy(VkDevice device) { foreach (var layout in m_pipelineLayouts) { VulkanAPI.vkDestroyPipelineLayout(device, layout); } m_pipelineLayouts = null; foreach (var layout in m_descLayouts) { VulkanAPI.vkDestroyDescriptorSetLayout(device, layout); } if (m_descriptorPool != null) { VulkanAPI.vkDestroyDescriptorPool(device, m_descriptorPool); } m_descriptorPool = null; foreach (var buffer in m_buffers) { VulkanAPI.vkDestroyBuffer(device, buffer); } m_buffers = null; foreach (var mem in m_memories) { VulkanAPI.vkFreeMemory(device, mem); } }
private void CreateVertexBuffer(VkDevice device, VkPhysicalDevice physicalDevice) { // 初期頂点データ. var vertices = new Vertex[3] { new Vertex() { Position = new vec3(-.5f, 0.5f, 0.0f), Color = new vec4(0.0f, 0.0f, 1.0f, 1.0f) }, new Vertex() { Position = new vec3(+.5f, 0.5f, 0.0f), Color = new vec4(0.0f, 1.0f, 0.0f, 1.0f) }, new Vertex() { Position = new vec3(0.0f, -.5f, 0.0f), Color = new vec4(1.0f, 0.0f, 0.0f, 1.0f) }, }; var bufferSize = Marshal.SizeOf <Vertex>() * vertices.Length; VkMemoryPropertyFlags memoryFlags = VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; SampleHelpers.CreateBuffer(device, physicalDevice, bufferSize, VkBufferUsageFlags.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, memoryFlags, out m_vertexBuffer, out m_vertexBufferMemory); // 初期頂点データの書き込み. MappedMemoryStream mappedStream; VulkanAPI.vkMapMemory(device, m_vertexBufferMemory, 0, VkDeviceSize.VK_WHOLE_SIZE, 0, out mappedStream); mappedStream.Write(vertices); VulkanAPI.vkUnmapMemory(device, m_vertexBufferMemory); }
private void setImageMemoryBarrier(VkCommandBuffer command, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout, VkImage image, VkImageAspectFlags aspectFlags) { var imageMemoryBarrier = new VkImageMemoryBarrier() { srcAccessMask = srcAccessMask, dstAccessMask = dstAccessMask, oldLayout = oldLayout, newLayout = newLayout, srcQueueFamilyIndex = ~0u, dstQueueFamilyIndex = ~0u, subresourceRange = new VkImageSubresourceRange { aspectMask = aspectFlags, baseMipLevel = 0, levelCount = 1, baseArrayLayer = 0, layerCount = 1, }, image = image }; VulkanAPI.vkCmdPipelineBarrier( command, VkPipelineStageFlags.VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VkPipelineStageFlags.VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, null, // MemoryBarriers null, // BufferMemoryBarriers new VkImageMemoryBarrier[] { imageMemoryBarrier } ); }
public void CreateCubeModel(VkDevice device, VkPhysicalDevice physicalDevice) { var cubeVertices = CubeModel.GetVertices(); var cubeIndices = CubeModel.GetIndices(); var vbSize = Marshal.SizeOf <CubeModel.Vertex>() * cubeVertices.Length; var ibSize = Marshal.SizeOf <ushort>() * cubeIndices.Length; VkMemoryPropertyFlags flags = VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; SampleHelpers.CreateBuffer(device, physicalDevice, vbSize, VkBufferUsageFlags.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, flags, out m_vertexBuffer, out m_vertexBufferMemory); SampleHelpers.CreateBuffer(device, physicalDevice, ibSize, VkBufferUsageFlags.VK_BUFFER_USAGE_INDEX_BUFFER_BIT, flags, out m_indexBuffer, out m_indexBufferMemory); // 初期データの書き込み. MappedMemoryStream mapped; VulkanAPI.vkMapMemory(device, m_vertexBufferMemory, 0, VkDeviceSize.VK_WHOLE_SIZE, 0, out mapped); mapped.Write(cubeVertices); VulkanAPI.vkUnmapMemory(device, m_vertexBufferMemory); VulkanAPI.vkMapMemory(device, m_indexBufferMemory, 0, VkDeviceSize.VK_WHOLE_SIZE, 0, out mapped); mapped.Write(cubeIndices); VulkanAPI.vkUnmapMemory(device, m_indexBufferMemory); m_resourceManager.Regist(m_vertexBuffer, m_vertexBufferMemory); m_resourceManager.Regist(m_indexBuffer, m_indexBufferMemory); }
/// <summary> /// パイプラインレイアウトを構築します。 /// </summary> /// <returns></returns> private VkPipelineLayout CreatePipelineLayout(VkDevice device) { var createInfo = new VkPipelineLayoutCreateInfo(); VkPipelineLayout layout = null; VulkanAPI.vkCreatePipelineLayout(device, ref createInfo, out layout); return(layout); }
private void Vkctrl_VulkanInitialized(object sender, SharpVulkanWpf.VulkanEventArgs args) { var device = args.Device; var commandPoolCreateInfo = new VkCommandPoolCreateInfo() { queueFamilyIndex = args.GraphicsQueueIndex, flags = VkCommandPoolCreateFlags.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, }; VulkanAPI.vkCreateCommandPool(device, ref commandPoolCreateInfo, out m_commandPool); var allocateInfo = new VkCommandBufferAllocateInfo() { commandBufferCount = 1, commandPool = m_commandPool, }; VulkanAPI.vkAllocateCommandBuffers(device, ref allocateInfo, out m_commandBuffers); // 頂点入力情報の構築. m_vertexInputState = CreateVertexInputState(); // プリミティブの情報 トライアングルリストでデータが生成されている. m_inputAssemblyState = new VkPipelineInputAssemblyStateCreateInfo() { topology = VkPrimitiveTopology.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST }; // シェーダーステージ情報の構築. m_shaderStages = new VkPipelineShaderStageCreateInfo[2] { SampleHelpers.CreateShader(device, "resource/simpleVS.spv", VkShaderStageFlagBits.VK_SHADER_STAGE_VERTEX_BIT), SampleHelpers.CreateShader(device, "resource/simpleFS.spv", VkShaderStageFlagBits.VK_SHADER_STAGE_FRAGMENT_BIT), }; // ラスタライザーステートの構築. m_rasterizationState = new VkPipelineRasterizationStateCreateInfo(); // デプスステンシルステートの構築. m_depthStencilState = new VkPipelineDepthStencilStateCreateInfo(); // カラーブレンドステートの構築. m_colorBlendState = new VkPipelineColorBlendStateCreateInfo(); var colorBlendAttachment = new VkPipelineColorBlendAttachmentState(); m_colorBlendState.attachments = new[] { colorBlendAttachment }; // マルチサンプルステートの構築. m_multisampleState = new VkPipelineMultisampleStateCreateInfo(); // パイプラインレイアウトの構築. m_pipelineLayout = CreatePipelineLayout(device); // ビューポートステートの構築. m_viewportState = CreateViewportState(); // グラフィックスパイプラインを構築. m_graphicsPipeline = CreateGraphicsPipeline(device, vkctrl.GetControlRenderPass()); // 頂点バッファの作成. CreateVertexBuffer(device, args.PhysicalDevice); }
public VkDescriptorSetLayout CreateDescriptorSetLayout(VkDevice device, VkDescriptorSetLayoutBinding[] bindings) { VkDescriptorSetLayout layout = null; var descriptorSetLayoutCreateInfo = new VkDescriptorSetLayoutCreateInfo(); descriptorSetLayoutCreateInfo.bindings = bindings; VulkanAPI.vkCreateDescriptorSetLayout(device, ref descriptorSetLayoutCreateInfo, out layout); m_descLayouts.Add(layout); return(layout); }
/// <summary> /// パイプラインレイアウトを構築します。 /// </summary> /// <returns></returns> private VkPipelineLayout CreatePipelineLayout(VkDevice device) { var createInfo = new VkPipelineLayoutCreateInfo(); createInfo.setLayouts = new[] { m_descriptorSetLayout }; VkPipelineLayout layout = null; VulkanAPI.vkCreatePipelineLayout(device, ref createInfo, out layout); return(layout); }
private void Vkctrl_VulkanClosing(object sender, SharpVulkanWpf.VulkanEventArgs args) { // 本クラスで作ったVulkanの各リソースを破棄する. var dev = args.Device; VulkanAPI.vkFreeCommandBuffers(dev, m_commandPool, m_commandBuffers); VulkanAPI.vkDestroyCommandPool(dev, m_commandPool); m_commandBuffers = null; m_commandPool = null; }
public VkPipelineLayout CreatePipelineLayout(VkDevice device, VkDescriptorSetLayout descSetLayout) { var createInfo = new VkPipelineLayoutCreateInfo(); createInfo.setLayouts = new[] { descSetLayout }; VkPipelineLayout layout = null; VulkanAPI.vkCreatePipelineLayout(device, ref createInfo, out layout); m_pipelineLayouts.Add(layout); return(layout); }
private void Vkctrl_VulkanRendering(object sender, SharpVulkanWpf.VulkanEventArgs args) { var device = args.Device; var image = vkctrl.AcquireNextImage(); var command = m_commandBuffers[0]; VulkanAPI.vkBeginCommandBuffer(command); VkClearColorValue clearColor = new VkClearColorValue(); clearColor.valF32.R = 0.125f; clearColor.valF32.G = 0.25f; clearColor.valF32.B = (float)(0.5f * Math.Sin(m_frameCount * 0.1) + 0.5); clearColor.valF32.A = 1.0f; VkImageSubresourceRange range = new VkImageSubresourceRange() { baseMipLevel = 0, levelCount = 1, baseArrayLayer = 0, layerCount = 1, aspectMask = VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT }; setImageMemoryBarrier(command, VkAccessFlags.VK_ACCESS_MEMORY_READ_BIT, VkAccessFlags.VK_ACCESS_TRANSFER_WRITE_BIT, VkImageLayout.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image, VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT); VulkanAPI.vkCmdClearColorImage(command, image, VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, ref clearColor, new VkImageSubresourceRange[] { range }); // Present のためにレイアウト変更 setImageMemoryBarrier(command, VkAccessFlags.VK_ACCESS_TRANSFER_WRITE_BIT, VkAccessFlags.VK_ACCESS_MEMORY_READ_BIT, VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VkImageLayout.VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, image, VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT); VulkanAPI.vkEndCommandBuffer(command); var submitInfo = new VkSubmitInfo() { commandBuffers = new[] { command } }; VulkanAPI.vkQueueSubmit(args.GraphicsQueue, new VkSubmitInfo[] { submitInfo }, null); vkctrl.SwapBuffers(); m_frameCount++; }
private void Vkctrl_VulkanRendering(object sender, SharpVulkanWpf.VulkanEventArgs args) { var device = args.Device; var image = vkctrl.AcquireNextImage(); var framebuffer = vkctrl.AcquireNextFramebuffer(); var command = m_commandBuffers[0]; VulkanAPI.vkBeginCommandBuffer(command); VkClearColorValue clearColor = new VkClearColorValue(); clearColor.valF32.R = 0.125f; clearColor.valF32.G = 0.25f; clearColor.valF32.B = (float)(0.5f * Math.Sin(m_frameCount * 0.1) + 0.5); clearColor.valF32.A = 1.0f; var renderArea = new VkRect2D() { offset = new VkOffset2D(), extent = vkctrl.GetCurrentExtent(), }; var renderPassBeginInfo = new VkRenderPassBeginInfo() { framebuffer = framebuffer, renderArea = renderArea, renderPass = vkctrl.GetControlRenderPass(), pClearValues = new[] { new VkClearValue() { color = clearColor } } }; VulkanAPI.vkCmdBeginRenderPass(command, ref renderPassBeginInfo, VkSubpassContents.VK_SUBPASS_CONTENTS_INLINE); VulkanAPI.vkCmdBindPipeline(command, VkPipelineBindPoint.VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline); VulkanAPI.vkCmdBindVertexBuffers(command, 0, 1, new[] { m_vertexBuffer }, new[] { (VkDeviceSize)0 }); VulkanAPI.vkCmdDraw(command, 3, 1, 0, 0); VulkanAPI.vkCmdEndRenderPass(command); VulkanAPI.vkEndCommandBuffer(command); var submitInfo = new VkSubmitInfo() { commandBuffers = new[] { command } }; VulkanAPI.vkQueueSubmit(args.GraphicsQueue, new VkSubmitInfo[] { submitInfo }, null); vkctrl.SwapBuffers(); m_frameCount++; }
public VkDescriptorPool CreateDescriptorPool(VkDevice device, VkDescriptorPoolSize[] descPoolSize, int maxSets) { var descriptorPoolCreateInfo = new VkDescriptorPoolCreateInfo() { poolSizes = descPoolSize, maxSets = (uint)maxSets, flags = VkDescriptorPoolCreateFlags.VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, }; VulkanAPI.vkCreateDescriptorPool(device, ref descriptorPoolCreateInfo, out m_descriptorPool); return(m_descriptorPool); }
private void PrepareDescriptor(VkDevice device) { // 定数バッファを1つだけ持つものを作る. VkDescriptorPoolSize descriptorPoolSize = new VkDescriptorPoolSize() { descriptorCount = 1, type = VkDescriptorType.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, }; var descriptorPoolCreateInfo = new VkDescriptorPoolCreateInfo() { poolSizes = new[] { descriptorPoolSize }, maxSets = 1, flags = VkDescriptorPoolCreateFlags.VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, }; VulkanAPI.vkCreateDescriptorPool(device, ref descriptorPoolCreateInfo, out m_descriptorPool); // ディスクリプタセットレイアウトの作成. // 今は定数バッファを1つ持つだけのものを作成. var descriptorLayoutBinding = new VkDescriptorSetLayoutBinding(); descriptorLayoutBinding.binding = 0; descriptorLayoutBinding.descriptorCount = 1; descriptorLayoutBinding.descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; descriptorLayoutBinding.stageFlags = VkShaderStageFlagBits.VK_SHADER_STAGE_VERTEX_BIT; var descriptorSetLayoutCreateInfo = new VkDescriptorSetLayoutCreateInfo(); descriptorSetLayoutCreateInfo.bindings = new[] { descriptorLayoutBinding }; VulkanAPI.vkCreateDescriptorSetLayout(device, ref descriptorSetLayoutCreateInfo, out m_descriptorSetLayout); // ディスクリプタセットを作成. VkDescriptorSet[] descriptorSets; var descriptorSetAllocateInfo = new VkDescriptorSetAllocateInfo(m_descriptorPool, new[] { m_descriptorSetLayout }); VulkanAPI.vkAllocateDescriptorSets(device, ref descriptorSetAllocateInfo, out descriptorSets); m_descriptorSet = descriptorSets[0]; // ディスクリプタを更新. // 定数バッファ1つを持つレイアウトでディスクリプタを作る. VkDescriptorBufferInfo descUniformBufferInfo = new VkDescriptorBufferInfo(); descUniformBufferInfo.buffer = m_uniformBuffer; descUniformBufferInfo.range = Marshal.SizeOf <Transform>(); var descriptor = new VkWriteDescriptorSet(); descriptor.descriptorCount = 1; descriptor.descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; descriptor.pBufferInfo = new[] { descUniformBufferInfo }; descriptor.dstBinding = 0; descriptor.dstSet = m_descriptorSet; VulkanAPI.vkUpdateDescriptorSets(device, new[] { descriptor }, null); }
/// <summary> /// リサイズの処理が必要になったときに呼ばれます. /// </summary> /// <param name="e"></param> private void Vkctrl_VulkanResized(SharpVulkanWpf.VulkanSizeChangedEventArgs e) { var device = e.Device; m_viewportState = CreateViewportState(); if (m_graphicsPipeline != null) { VulkanAPI.vkDestroyPipeline(device, m_graphicsPipeline); } var renderPass = vkctrl.GetControlRenderPass(); m_graphicsPipeline = CreateGraphicsPipeline(device, renderPass); }
private void Vkctrl_VulkanClosing(object sender, SharpVulkanWpf.VulkanEventArgs args) { // 本クラスで作ったVulkanの各リソースを破棄する. var dev = args.Device; VulkanAPI.vkDestroyPipeline(dev, m_graphicsPipeline); m_graphicsPipeline = null; m_shaderStages.Select(x => x.module).ToList().ForEach(x => VulkanAPI.vkDestroyShaderModule(dev, x)); m_resourceManager.Destroy(dev); VulkanAPI.vkFreeCommandBuffers(dev, m_commandPool, m_commandBuffers); VulkanAPI.vkDestroyCommandPool(dev, m_commandPool); m_commandBuffers = null; m_commandPool = null; }
private void Vkctrl_VulkanInitialized(object sender, SharpVulkanWpf.VulkanEventArgs args) { var device = args.Device; var commandPoolCreateInfo = new VkCommandPoolCreateInfo() { queueFamilyIndex = args.GraphicsQueueIndex, flags = VkCommandPoolCreateFlags.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, }; VulkanAPI.vkCreateCommandPool(device, ref commandPoolCreateInfo, out m_commandPool); var allocateInfo = new VkCommandBufferAllocateInfo() { commandBufferCount = 1, commandPool = m_commandPool, }; VulkanAPI.vkAllocateCommandBuffers(device, ref allocateInfo, out m_commandBuffers); }
/// <summary> /// バッファの作成 /// </summary> /// <param name="device"></param> /// <param name="physicalDevice"></param> /// <param name="bufferSize"></param> /// <param name="usageFlags"></param> /// <param name="memoryFlags"></param> /// <param name="buffer"></param> /// <param name="memory"></param> public static void CreateBuffer(VkDevice device, VkPhysicalDevice physicalDevice, int bufferSize, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryFlags, out VkBuffer buffer, out VkDeviceMemory memory) { buffer = null; memory = null; var bufferCreateInfo = new VkBufferCreateInfo(usageFlags, bufferSize); if (VkResult.VK_SUCCESS != VulkanAPI.vkCreateBuffer(device, ref bufferCreateInfo, out buffer)) { return; } VkMemoryRequirements requirements; VulkanAPI.vkGetBufferMemoryRequirements(device, buffer, out requirements); if (VkResult.VK_SUCCESS != VulkanAPI.vkAllocateMemory(device, physicalDevice, ref requirements, memoryFlags, out memory)) { return; } VulkanAPI.vkBindBufferMemory(device, buffer, memory, 0); }
private VkPipeline CreateGraphicsPipeline(VkDevice device, VkRenderPass renderPass) { VkPipeline pipeline = null; var createInfo = new VkGraphicsPipelineCreateInfo() { inputAssemblyState = m_inputAssemblyState, vertexInputState = m_vertexInputState, pRasterizationState = m_rasterizationState, pDepthStencilState = m_depthStencilState, pColorBlendState = m_colorBlendState, pMultisampleState = m_multisampleState, pStages = m_shaderStages, viewportState = m_viewportState, layout = m_pipelineLayout, renderPass = renderPass }; VulkanAPI.vkCreateGraphicsPipelines(device, null, 1, ref createInfo, out pipeline); return(pipeline); }
private void PrepareDescriptor(VkDevice device) { // 今は定数バッファを1つを格納できるだけのディスクリプタプールを準備. var descriptorPoolSize = new VkDescriptorPoolSize() { descriptorCount = 1, type = VkDescriptorType.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, }; m_descriptorPool = m_resourceManager.CreateDescriptorPool(device, new[] { descriptorPoolSize }, 1); // ディスクリプタセットレイアウトの作成. // - 定数バッファを1つ var descLayoutBinding = new VkDescriptorSetLayoutBinding() { binding = 0, descriptorCount = 1, descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, stageFlags = VkShaderStageFlagBits.VK_SHADER_STAGE_VERTEX_BIT }; m_descriptorSetLayout = m_resourceManager.CreateDescriptorSetLayout(device, new[] { descLayoutBinding }); // ディスクリプタを作成&更新. VkDescriptorSet[] descriptorSets; var descriptorSetAllocateInfo = new VkDescriptorSetAllocateInfo(m_descriptorPool, new[] { m_descriptorSetLayout }); VulkanAPI.vkAllocateDescriptorSets(device, ref descriptorSetAllocateInfo, out descriptorSets); m_descriptorSet = descriptorSets[0]; var descUniform = new VkDescriptorBufferInfo() { buffer = m_uniformBuffer, range = Marshal.SizeOf <Transform>(), }; var descForUniform = SampleHelpers.CreateDescriptorFromUniformBuffer(0, descUniform, m_descriptorSet); var descriptorWrites = new[] { descForUniform }; VulkanAPI.vkUpdateDescriptorSets(device, descriptorWrites, null); }
private void CreateTexture(VkDevice device, VkPhysicalDevice physicalDevice, VkQueue graphicsQueue) { SimpleTgaReader tex = new SimpleTgaReader("resource/texture.tga"); var command = m_commandBuffers[1]; SampleHelpers.CreateTexture(device, physicalDevice, tex.Width, tex.Height, tex.ImageData, out m_image, out m_imageMemory, graphicsQueue, command); // イメージビューの作成. var imageViewCreateInfo = new VkImageViewCreateInfo() { image = m_image, viewType = VkImageViewType.VK_IMAGE_VIEW_TYPE_2D, format = VkFormat.VK_FORMAT_B8G8R8A8_UNORM, components = new VkComponentMapping(), subresourceRange = new VkImageSubresourceRange() { aspectMask = VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT, baseArrayLayer = 0, baseMipLevel = 0, levelCount = 1, layerCount = 1, } }; VulkanAPI.vkCreateImageView(device, ref imageViewCreateInfo, out m_imageView); // サンプラーの作成. var samplerCreateInfo = new VkSamplerCreateInfo() { magFilter = VkFilter.VK_FILTER_LINEAR, minFilter = VkFilter.VK_FILTER_LINEAR, mipmapMode = VkSamplerMipmapMode.VK_SAMPLER_MIPMAP_MODE_NEAREST, addressModeU = VkSamplerAddressMode.VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, addressModeV = VkSamplerAddressMode.VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, }; VulkanAPI.vkCreateSampler(device, ref samplerCreateInfo, out m_imageSampler); }
/// <summary> /// SPVシェーダーファイルを読み込んで VkPipelineShaderStageCreateInfo を作成します. /// </summary> /// <param name="device"></param> /// <param name="shaderFile"></param> /// <param name="stageFlag"></param> /// <returns></returns> public static VkPipelineShaderStageCreateInfo CreateShader(VkDevice device, string shaderFile, VkShaderStageFlagBits stageFlag) { var stageCreateInfo = new VkPipelineShaderStageCreateInfo(); using (var fs = new FileStream(shaderFile, FileMode.Open, FileAccess.Read)) { var code = new byte[fs.Length]; fs.Read(code, 0, (int)fs.Length); var shaderModuleCreateInfo = new VkShaderModuleCreateInfo() { shaderCodeBinary = code, }; VkShaderModule shaderModule; VulkanAPI.vkCreateShaderModule(device, ref shaderModuleCreateInfo, out shaderModule); stageCreateInfo.flags = 0; stageCreateInfo.stage = stageFlag; stageCreateInfo.pName = "main"; stageCreateInfo.module = shaderModule; } return(stageCreateInfo); }
public static void CreateTexture(VkDevice device, VkPhysicalDevice physicalDevice, int width, int height, byte[] imageSource, out VkImage image, out VkDeviceMemory memory, VkQueue queue, VkCommandBuffer workCommandBuffer) { var imageCreateInfo = new VkImageCreateInfo() { imageType = VkImageType.VK_IMAGE_TYPE_2D, format = VkFormat.VK_FORMAT_B8G8R8A8_UNORM, extent = new VkExtent3D(width, height), mipLevels = 1, usage = VkImageUsageFlags.VK_IMAGE_USAGE_TRANSFER_DST_BIT | VkImageUsageFlags.VK_IMAGE_USAGE_SAMPLED_BIT, }; VulkanAPI.vkCreateImage(device, ref imageCreateInfo, out image); VkMemoryRequirements requirements; VulkanAPI.vkGetImageMemoryRequirements(device, image, out requirements); VkMemoryPropertyFlags memoryFlags = VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; VulkanAPI.vkAllocateMemory(device, physicalDevice, ref requirements, memoryFlags, out memory); VulkanAPI.vkBindImageMemory(device, image, memory, 0); // ステージングバッファ経由で転送. VkBuffer staging; VkDeviceMemory stagingMemory; var stagingFlags = VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VkMemoryPropertyFlags.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; CreateBuffer(device, physicalDevice, imageSource.Length, VkBufferUsageFlags.VK_BUFFER_USAGE_TRANSFER_SRC_BIT, stagingFlags, out staging, out stagingMemory); MappedMemoryStream mappedStream; VulkanAPI.vkMapMemory(device, stagingMemory, 0, VkDeviceSize.VK_WHOLE_SIZE, 0, out mappedStream); mappedStream.Write(imageSource); VulkanAPI.vkUnmapMemory(device, stagingMemory); var copyRegion = new VkBufferImageCopy() { imageExtent = new VkExtent3D(width, height), bufferImageHeight = (uint)height, imageSubresource = new VkImageSubresourceLayers() { aspectMask = VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT, mipLevel = 0, baseArrayLayer = 0, layerCount = 1, } }; // 一時的なコマンドバッファで転送処理. var command = workCommandBuffer; VulkanAPI.vkBeginCommandBuffer(command); setImageMemoryBarrier(command, 0, VkAccessFlags.VK_ACCESS_TRANSFER_WRITE_BIT, VkImageLayout.VK_IMAGE_LAYOUT_UNDEFINED, VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image, VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT); VulkanAPI.vkCmdCopyBufferToImage(command, staging, image, VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, new[] { copyRegion }); setImageMemoryBarrier(command, VkAccessFlags.VK_ACCESS_TRANSFER_WRITE_BIT, VkAccessFlags.VK_ACCESS_SHADER_READ_BIT, VkImageLayout.VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VkImageLayout.VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image, VkImageAspectFlags.VK_IMAGE_ASPECT_COLOR_BIT); VulkanAPI.vkEndCommandBuffer(command); var submitInfo = new VkSubmitInfo() { commandBuffers = new[] { command }, }; var fenceCreateInfo = new VkFenceCreateInfo() { }; VkFence fence; VulkanAPI.vkCreateFence(device, fenceCreateInfo, out fence); VulkanAPI.vkQueueSubmit(queue, new[] { submitInfo }, fence); VulkanAPI.vkWaitForFences(device, new[] { fence }, true, ulong.MaxValue); VulkanAPI.vkDestroyFence(device, fence); VulkanAPI.vkDestroyBuffer(device, staging); VulkanAPI.vkFreeMemory(device, stagingMemory); }
private void Vkctrl_VulkanRendering(object sender, SharpVulkanWpf.VulkanEventArgs args) { var device = args.Device; var image = vkctrl.AcquireNextImage(); var framebuffer = vkctrl.AcquireNextFramebuffer(); var command = m_commandBuffers[0]; VulkanAPI.vkBeginCommandBuffer(command); VkClearColorValue clearColor = new VkClearColorValue(); clearColor.valF32.R = 0.125f; clearColor.valF32.G = 0.25f; clearColor.valF32.B = 0.4f; clearColor.valF32.A = 1.0f; VkClearDepthStencilValue clearDepth = new VkClearDepthStencilValue() { depth = 1.0f, stencil = 0, }; var currentExtent = vkctrl.GetCurrentExtent(); // 定数バッファの更新. var sceneTrs = new Transform(); var aspect = (float)currentExtent.width / (float)currentExtent.height; var proj = mat4.Perspective((float)Math.PI / 3.0f, aspect, 1.0f, 100.0f); sceneTrs.World = mat4.RotateY(m_frameCount * 0.05f) * mat4.RotateX(m_frameCount * 0.01f); sceneTrs.View = mat4.LookAt(new vec3(0, 0, 6), new vec3(0, 0, 0), new vec3(0, 1, 0)); sceneTrs.Proj = proj; MappedMemoryStream mapped = null; VulkanAPI.vkMapMemory(device, m_uniformBufferMemory, 0, VkDeviceSize.VK_WHOLE_SIZE, 0, out mapped); mapped.Write(sceneTrs); VulkanAPI.vkUnmapMemory(device, m_uniformBufferMemory); var renderArea = new VkRect2D() { offset = new VkOffset2D(), extent = vkctrl.GetCurrentExtent(), }; var renderPassBeginInfo = new VkRenderPassBeginInfo() { framebuffer = framebuffer, renderArea = renderArea, renderPass = vkctrl.GetControlRenderPass(), pClearValues = new[] { new VkClearValue() { color = clearColor }, new VkClearValue() { depthStencil = clearDepth }, } }; VulkanAPI.vkCmdBeginRenderPass(command, ref renderPassBeginInfo, VkSubpassContents.VK_SUBPASS_CONTENTS_INLINE); VulkanAPI.vkCmdBindPipeline(command, VkPipelineBindPoint.VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline); VulkanAPI.vkCmdBindVertexBuffers(command, 0, 1, new[] { m_vertexBuffer }, new[] { (VkDeviceSize)0 }); VulkanAPI.vkCmdBindIndexBuffer(command, m_indexBuffer, 0, VkIndexType.VK_INDEX_TYPE_UINT16); VulkanAPI.vkCmdBindDescriptorSets(command, VkPipelineBindPoint.VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, new[] { m_descriptorSet }, null); VulkanAPI.vkCmdDrawIndexed(command, 36, 1, 0, 0, 0); VulkanAPI.vkCmdEndRenderPass(command); VulkanAPI.vkEndCommandBuffer(command); var submitInfo = new VkSubmitInfo() { commandBuffers = new[] { command } }; VulkanAPI.vkQueueSubmit(args.GraphicsQueue, submitInfo, null); vkctrl.SwapBuffers(); m_frameCount++; }
private void PrepareDescriptor(VkDevice device) { // 今は定数バッファを1つ、サンプラーを1つを格納できるだけのディスクリプタプールを準備. VkDescriptorPoolSize descriptorPoolSize = new VkDescriptorPoolSize() { descriptorCount = 1, type = VkDescriptorType.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, }; VkDescriptorPoolSize descriptorPoolSizeForSampler = new VkDescriptorPoolSize() { descriptorCount = 1, type = VkDescriptorType.VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, }; var descriptorPoolCreateInfo = new VkDescriptorPoolCreateInfo() { poolSizes = new[] { descriptorPoolSize, descriptorPoolSizeForSampler }, maxSets = 1, flags = VkDescriptorPoolCreateFlags.VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, }; VulkanAPI.vkCreateDescriptorPool(device, ref descriptorPoolCreateInfo, out m_descriptorPool); // ディスクリプタセットレイアウトの作成. // - 定数バッファを1つ // - テクスチャサンプラ1つ var descLayoutBindingForUniform = new VkDescriptorSetLayoutBinding(); descLayoutBindingForUniform.binding = 0; descLayoutBindingForUniform.descriptorCount = 1; descLayoutBindingForUniform.descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; descLayoutBindingForUniform.stageFlags = VkShaderStageFlagBits.VK_SHADER_STAGE_VERTEX_BIT; var descLayoutBindingForSampler = new VkDescriptorSetLayoutBinding(); descLayoutBindingForSampler.binding = 1; descLayoutBindingForSampler.descriptorCount = 1; descLayoutBindingForSampler.descriptorType = VkDescriptorType.VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; descLayoutBindingForSampler.stageFlags = VkShaderStageFlagBits.VK_SHADER_STAGE_FRAGMENT_BIT; var descriptorSetLayoutCreateInfo = new VkDescriptorSetLayoutCreateInfo(); descriptorSetLayoutCreateInfo.bindings = new[] { descLayoutBindingForUniform, descLayoutBindingForSampler }; VulkanAPI.vkCreateDescriptorSetLayout(device, ref descriptorSetLayoutCreateInfo, out m_descriptorSetLayout); // ディスクリプタを作成&更新. VkDescriptorSet[] descriptorSets; var descriptorSetAllocateInfo = new VkDescriptorSetAllocateInfo(m_descriptorPool, new[] { m_descriptorSetLayout }); VulkanAPI.vkAllocateDescriptorSets(device, ref descriptorSetAllocateInfo, out descriptorSets); m_descriptorSet = descriptorSets[0]; var descUniform = new VkDescriptorBufferInfo() { buffer = m_uniformBuffer, range = Marshal.SizeOf <Transform>(), }; var descSampler = new VkDescriptorImageInfo() { imageView = m_imageView, sampler = m_imageSampler, }; var descForUniform = SampleHelpers.CreateDescriptorFromUniformBuffer(0, descUniform, m_descriptorSet); var descForSampler = SampleHelpers.CreateDescriptorFromImageSampler(1, descSampler, m_descriptorSet); var descriptorWrites = new[] { descForUniform, descForSampler }; VulkanAPI.vkUpdateDescriptorSets(device, descriptorWrites, null); }