Пример #1
0
        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);
            }
        }
Пример #3
0
        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 }
                );
        }
Пример #5
0
        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);
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
        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);
        }
Пример #9
0
        /// <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++;
        }
Пример #13
0
        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);
        }
Пример #16
0
        /// <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);
        }
Пример #17
0
        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);
        }
Пример #19
0
        /// <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);
        }
Пример #20
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);
        }
Пример #21
0
        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);
        }
Пример #22
0
        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);
        }
Пример #23
0
        /// <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);
        }
Пример #24
0
        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);
        }
Пример #25
0
        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++;
        }
Пример #26
0
        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);
        }