Exemplo n.º 1
0
        public unsafe Mesh(VkDevice device, VkPhysicalDevice physicalDevice, T[] vertices, uint[] indices)
        {
            this.vertices = new FDataBuffer <T>(device, physicalDevice, vertices.Length, VkBufferUsageFlags.VertexBuffer,
                                                VkSharingMode.Exclusive);
            this.indices = new FDataBuffer <uint>(device, physicalDevice, indices.Length, VkBufferUsageFlags.IndexBuffer, VkSharingMode.Exclusive);

            Span <T> spanv = this.vertices.Map();
            T *      vptr;

            fixed(T *ptr = spanv)
            vptr = ptr;

            Parallel.For(0, vertices.Length, (i) =>
            {
                *(vptr + i) = vertices[i];
            });
            vptr  = null;
            spanv = this.vertices.UnMap();

            Span <uint> spani = this.indices.Map();
            uint *      iptr;

            fixed(uint *ptr = spani)
            iptr = ptr;

            Parallel.For(0, indices.Length, (i) =>
            {
                *(iptr + i) = indices[i];
            });
            iptr  = null;
            spani = this.indices.UnMap();
        }
Exemplo n.º 2
0
        private void CreateDepthImage(VkPhysicalDevice physicalDevice, uint width, uint height)
        {
            VkImageCreateInfo createInfo = VkImageCreateInfo.New();

            createInfo.imageType     = VkImageType.Image2D;
            createInfo.extent.width  = width;
            createInfo.extent.height = height;
            createInfo.extent.depth  = 1;
            createInfo.mipLevels     = 1;
            createInfo.arrayLayers   = 1;
            createInfo.format        = VkFormat.D32Sfloat;
            createInfo.tiling        = VkImageTiling.Optimal;
            createInfo.initialLayout = VkImageLayout.Undefined;
            createInfo.usage         = VkImageUsageFlags.DepthStencilAttachment;
            createInfo.sharingMode   = VkSharingMode.Exclusive;
            createInfo.samples       = VkSampleCountFlags.Count1;

            VkImage depthImage;

            Assert(vkCreateImage(device, &createInfo, null, &depthImage));

            VkMemoryRequirements memoryRequirements;

            vkGetImageMemoryRequirements(device, depthImage, &memoryRequirements);

            VkPhysicalDeviceMemoryProperties memoryProperties = new VkPhysicalDeviceMemoryProperties();

            vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties);

            VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New();

            allocateInfo.allocationSize  = memoryRequirements.size;
            allocateInfo.memoryTypeIndex = FDataBuffer <byte> .SelectMemoryType(memoryProperties, memoryRequirements.memoryTypeBits,
                                                                                VkMemoryPropertyFlags.DeviceLocal);

            VkDeviceMemory depthImageMemory;

            Assert(vkAllocateMemory(device, &allocateInfo, null, &depthImageMemory));

            vkBindImageMemory(device, depthImage, depthImageMemory, 0);

            this.depthImage       = depthImage;
            this.depthImageMemory = depthImageMemory;
        }
Exemplo n.º 3
0
        private void UpdateUniformData(FDataBuffer <float> uniformBuffer, uint swapchainImageIndex)
        {
            VkDescriptorBufferInfo bufferInfo = new VkDescriptorBufferInfo();

            bufferInfo.buffer = uniformBuffer.Buffer;
            bufferInfo.offset = 0;
            bufferInfo.range  = (uint)uniformBuffer.Length * 4;

            VkWriteDescriptorSet[] writes = new VkWriteDescriptorSet[1];
            writes[0].dstSet          = descriptorSets[swapchainImageIndex];
            writes[0].dstBinding      = 1;
            writes[0].dstArrayElement = 0;
            writes[0].descriptorType  = VkDescriptorType.UniformBuffer;
            writes[0].descriptorCount = 1;
            writes[0].pBufferInfo     = &bufferInfo;

            fixed(VkWriteDescriptorSet *ptr = writes)
            vkUpdateDescriptorSets(device, (uint)writes.Length, ptr, 0, null);
        }
Exemplo n.º 4
0
        public static FDataBuffer <float> CreateUniformBuffer(VkDevice device, VkPhysicalDevice physicalDevice, int modelCount)
        {
            FDataBuffer <float> buffer = new FDataBuffer <float>(device, physicalDevice, 16 * 4 + 16 * 4 + (16 * modelCount) * 4,
                                                                 VkBufferUsageFlags.UniformBuffer, VkSharingMode.Exclusive);

            float[]      id     = Matrix4x4.Identity.ToFloatArray();
            Span <float> idSpan = id.AsSpan();

            Span <float> span = buffer.Map();

            for (int i = 0; i < span.Length; i += 16)
            {
                Span <float> mat = span.Slice(i, 16);
                for (int j = 0; j < mat.Length; j++)
                {
                    mat[j] = idSpan[j];
                }
            }
            span = buffer.UnMap();
            return(buffer);
        }
Exemplo n.º 5
0
        private static VkImage LoadTexture(VkDevice device, VkPhysicalDevice physicalDevice, int cmdPoolID, VkQueue queue, string[] paths, uint mipLevels)
        {
            Bitmap[]             bitmaps    = new Bitmap[paths.Length];
            FDataBuffer <byte>[] tempBuffer = new FDataBuffer <byte> [paths.Length];

            uint width = 0, height = 0;

            for (int j = 0; j < paths.Length; j++)
            {
                bitmaps[j] = new Bitmap(System.Drawing.Image.FromFile(paths[j]));

                var data = bitmaps[j].LockBits(new Rectangle(0, 0, bitmaps[j].Width, bitmaps[j].Height), System.Drawing.Imaging.ImageLockMode.ReadOnly,
                                               bitmaps[j].PixelFormat);
                width  = (uint)data.Width;
                height = (uint)data.Height;//TODO add size check


                Span <byte> img = new Span <byte>((void *)data.Scan0, data.Stride * data.Height);

                tempBuffer[j] = new FDataBuffer <byte>(device, physicalDevice, img.Length, VkBufferUsageFlags.TransferSrc,
                                                       VkSharingMode.Exclusive);

                Span <byte> buffer = tempBuffer[j].Map();
                for (int i = 0; i < img.Length; i += 4)
                {
                    buffer[i + 2] = img[i];
                    buffer[i + 1] = img[i + 1];
                    buffer[i]     = img[i + 2];
                    buffer[i + 3] = img[i + 3];
                }
                buffer = tempBuffer[j].UnMap();
            }

            VkImage        texture = VkImage.Null;
            VkDeviceMemory memory  = VkDeviceMemory.Null;

            VkImageCreateInfo createInfo = VkImageCreateInfo.New();

            createInfo.imageType     = VkImageType.Image2D;
            createInfo.extent.width  = width;
            createInfo.extent.height = height;
            createInfo.extent.depth  = 1;
            createInfo.mipLevels     = mipLevels;
            createInfo.arrayLayers   = (uint)paths.Length;
            createInfo.format        = VkFormat.R8g8b8a8Unorm;
            createInfo.tiling        = VkImageTiling.Optimal;
            createInfo.initialLayout = VkImageLayout.Undefined;
            createInfo.usage         = VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferSrc;
            createInfo.sharingMode   = VkSharingMode.Exclusive;
            createInfo.samples       = VkSampleCountFlags.Count1;

            Assert(vkCreateImage(device, &createInfo, null, &texture));

            VkMemoryRequirements memoryRequirements;

            vkGetImageMemoryRequirements(device, texture, &memoryRequirements);

            VkPhysicalDeviceMemoryProperties memoryProperties = new VkPhysicalDeviceMemoryProperties();

            vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties);

            VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New();

            allocateInfo.allocationSize  = memoryRequirements.size;
            allocateInfo.memoryTypeIndex = FDataBuffer <byte> .SelectMemoryType(memoryProperties, memoryRequirements.memoryTypeBits,
                                                                                VkMemoryPropertyFlags.DeviceLocal);

            Assert(vkAllocateMemory(device, &allocateInfo, null, &memory));

            vkBindImageMemory(device, texture, memory, 0);

            VkCommandBufferAllocateInfo pAllocateInfo = VkCommandBufferAllocateInfo.New();

            pAllocateInfo.commandPool        = CommandPoolManager.GetPool(cmdPoolID);
            pAllocateInfo.level              = VkCommandBufferLevel.Primary;
            pAllocateInfo.commandBufferCount = 1;

            VkCommandBuffer cmdBuffer = VkCommandBuffer.Null;

            Assert(vkAllocateCommandBuffers(device, &pAllocateInfo, &cmdBuffer));

            VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New();

            beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit;

            Assert(vkBeginCommandBuffer(cmdBuffer, &beginInfo));

            VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New();

            imageMemoryBarrier.srcAccessMask       = VkAccessFlags.None;
            imageMemoryBarrier.dstAccessMask       = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite;
            imageMemoryBarrier.oldLayout           = VkImageLayout.Undefined;
            imageMemoryBarrier.newLayout           = VkImageLayout.TransferDstOptimal;
            imageMemoryBarrier.srcQueueFamilyIndex = VulkanNative.QueueFamilyIgnored;
            imageMemoryBarrier.dstQueueFamilyIndex = VulkanNative.QueueFamilyIgnored;
            imageMemoryBarrier.image            = texture;
            imageMemoryBarrier.subresourceRange = new VkImageSubresourceRange()
            {
                baseMipLevel   = 0,
                levelCount     = mipLevels,
                baseArrayLayer = 0,
                layerCount     = (uint)paths.Length,
                aspectMask     = VkImageAspectFlags.Color
            };

            vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion,
                                 0, null, 0, null, 1, &imageMemoryBarrier);

            for (int j = 0; j < tempBuffer.Length; j++)
            {
                VkBufferImageCopy region = new VkBufferImageCopy();
                region.bufferOffset      = 0;
                region.bufferRowLength   = 0;
                region.bufferImageHeight = 0;

                region.imageSubresource.aspectMask     = VkImageAspectFlags.Color;
                region.imageSubresource.mipLevel       = 0;
                region.imageSubresource.baseArrayLayer = (uint)j;
                region.imageSubresource.layerCount     = 1;

                region.imageOffset = new VkOffset3D();
                region.imageExtent = new VkExtent3D()
                {
                    width = width, height = height, depth = 1
                };

                vkCmdCopyBufferToImage(cmdBuffer, tempBuffer[j].Buffer, texture, VkImageLayout.TransferDstOptimal, 1, &region);
            }

            imageMemoryBarrier.oldLayout = VkImageLayout.TransferDstOptimal;
            imageMemoryBarrier.newLayout = VkImageLayout.ShaderReadOnlyOptimal;

            vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion,
                                 0, null, 0, null, 1, &imageMemoryBarrier);

            Assert(vkEndCommandBuffer(cmdBuffer));

            VkSubmitInfo submitInfo = VkSubmitInfo.New();

            submitInfo.commandBufferCount = 1;
            submitInfo.pCommandBuffers    = &cmdBuffer;

            Assert(vkQueueSubmit(queue, 1, &submitInfo, VkFence.Null));
            Assert(vkQueueWaitIdle(queue));
            vkFreeCommandBuffers(device, CommandPoolManager.GetPool(cmdPoolID), 1, &cmdBuffer);

            return(texture);
        }
Exemplo n.º 6
0
        public FGraphicsPipeline(VkDevice device, VkPhysicalDevice physicalDevice, VkPipelineCache pipelineCache, VkRenderPass renderPass,
                                 string shaderPath, uint swapchainImageCount, FTexture textureArray)
        {
            this.device = device;
            this.swapchainImageCount = swapchainImageCount;
            this.renderPass          = renderPass;

            desclayout     = CreateDescriptorLayout(device, 1);
            descriptorPool = CreateDescriptorPool(device, swapchainImageCount, 7);
            descriptorSets = AllocateDescriptorSets(device, desclayout, descriptorPool,
                                                    swapchainImageCount);

            sampler = CreateSampler(device, textureArray.MipLevels);
            for (int i = 0; i < swapchainImageCount; i++)
            {
                VkDescriptorImageInfo imageInfo = new VkDescriptorImageInfo();
                imageInfo.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
                imageInfo.imageView   = textureArray.imageView;
                imageInfo.sampler     = sampler;

                VkWriteDescriptorSet[] writes = new VkWriteDescriptorSet[1];
                writes[0].dstSet          = descriptorSets[i];
                writes[0].dstBinding      = 0;
                writes[0].dstArrayElement = 0;
                writes[0].descriptorType  = VkDescriptorType.CombinedImageSampler;
                writes[0].descriptorCount = 1;
                writes[0].pImageInfo      = &imageInfo;

                fixed(VkWriteDescriptorSet *ptr = writes)
                vkUpdateDescriptorSets(device, (uint)writes.Length, ptr, 0, null);
            }

            uniformdata = CreateUniformBuffer(device, physicalDevice, 1);

            VkShaderModule vs = LoadShader(device, $"{shaderPath}.vert.spv");
            VkShaderModule fs = LoadShader(device, $"{shaderPath}.frag.spv");


            VkGraphicsPipelineCreateInfo pCreateInfo = VkGraphicsPipelineCreateInfo.New();

            pCreateInfo.flags = VkPipelineCreateFlags.DisableOptimization;

            VkPipelineShaderStageCreateInfo[] shaderStages = new VkPipelineShaderStageCreateInfo[2];
            shaderStages[0]        = VkPipelineShaderStageCreateInfo.New();
            shaderStages[0].stage  = VkShaderStageFlags.Vertex;
            shaderStages[0].module = vs;

            byte[] vsFuncName = Encoding.UTF8.GetBytes("main" + char.MinValue);

            fixed(byte *ptr = &(vsFuncName[0]))
            shaderStages[0].pName = ptr;

            shaderStages[1]        = VkPipelineShaderStageCreateInfo.New();
            shaderStages[1].stage  = VkShaderStageFlags.Fragment;
            shaderStages[1].module = fs;
            byte[] fsFuncName = Encoding.UTF8.GetBytes("main" + char.MinValue);

            fixed(byte *ptr = &(fsFuncName[0]))
            shaderStages[1].pName = ptr;

            fixed(VkPipelineShaderStageCreateInfo *ptr = shaderStages)
            pCreateInfo.pStages = ptr;

            pCreateInfo.stageCount = 2;

            VkVertexInputBindingDescription[] bindings = new VkVertexInputBindingDescription[4];
            bindings[0]           = new VkVertexInputBindingDescription();
            bindings[0].binding   = 0;
            bindings[0].stride    = (uint)sizeof(VoxelRenderer.VoxelVertex);
            bindings[0].inputRate = VkVertexInputRate.Vertex;

            bindings[1]           = new VkVertexInputBindingDescription();
            bindings[1].binding   = 1;
            bindings[1].stride    = (uint)sizeof(VoxelRenderer.VoxelVertex);
            bindings[1].inputRate = VkVertexInputRate.Vertex;

            bindings[2]           = new VkVertexInputBindingDescription();
            bindings[2].binding   = 2;
            bindings[2].stride    = (uint)sizeof(VoxelRenderer.VoxelVertex);
            bindings[2].inputRate = VkVertexInputRate.Vertex;

            bindings[3]           = new VkVertexInputBindingDescription();
            bindings[3].binding   = 3;
            bindings[3].stride    = (uint)sizeof(VoxelRenderer.VoxelVertex);
            bindings[3].inputRate = VkVertexInputRate.Vertex;

            VkVertexInputAttributeDescription[] attribs = new VkVertexInputAttributeDescription[4];
            attribs[0].binding  = 0;
            attribs[0].location = 0;
            attribs[0].format   = VkFormat.R32g32b32Sfloat;
            attribs[0].offset   = 0;

            attribs[1].binding  = 1;
            attribs[1].location = 1;
            attribs[1].format   = VkFormat.R32g32b32Sfloat;
            attribs[1].offset   = 0;

            attribs[2].binding  = 2;
            attribs[2].location = 2;
            attribs[2].format   = VkFormat.R32g32b32Sfloat;
            attribs[2].offset   = 0;

            attribs[3].binding  = 3;
            attribs[3].location = 3;
            attribs[3].format   = VkFormat.R32Uint;
            attribs[3].offset   = 0;

            VkPipelineVertexInputStateCreateInfo vertexInput = VkPipelineVertexInputStateCreateInfo.New();

            fixed(VkVertexInputBindingDescription *ptr = bindings)
            vertexInput.pVertexBindingDescriptions = ptr;

            vertexInput.vertexBindingDescriptionCount = (uint)bindings.Length;

            fixed(VkVertexInputAttributeDescription *ptr = attribs)
            vertexInput.pVertexAttributeDescriptions = ptr;

            vertexInput.vertexAttributeDescriptionCount = (uint)attribs.Length;
            pCreateInfo.pVertexInputState = &vertexInput;

            VkPipelineInputAssemblyStateCreateInfo inputAssembly = VkPipelineInputAssemblyStateCreateInfo.New();

            inputAssembly.topology          = VkPrimitiveTopology.TriangleList;
            pCreateInfo.pInputAssemblyState = &inputAssembly;

            VkPipelineViewportStateCreateInfo viewportState = VkPipelineViewportStateCreateInfo.New();

            viewportState.viewportCount = 1;
            viewportState.scissorCount  = 1;
            pCreateInfo.pViewportState  = &viewportState;

            VkPipelineRasterizationStateCreateInfo rasterizationState = VkPipelineRasterizationStateCreateInfo.New();

            rasterizationState.lineWidth    = 1;
            rasterizationState.frontFace    = VkFrontFace.Clockwise;
            rasterizationState.cullMode     = VkCullModeFlags.Back;
            rasterizationState.polygonMode  = VkPolygonMode.Fill;//TODO add line debug render
            pCreateInfo.pRasterizationState = &rasterizationState;

            VkPipelineMultisampleStateCreateInfo multisampleState = VkPipelineMultisampleStateCreateInfo.New();

            multisampleState.rasterizationSamples = VkSampleCountFlags.Count1;
            pCreateInfo.pMultisampleState         = &multisampleState;

            VkPipelineDepthStencilStateCreateInfo depthState = VkPipelineDepthStencilStateCreateInfo.New();

            depthState.depthTestEnable     = VkBool32.True;
            depthState.depthWriteEnable    = VkBool32.True;
            depthState.depthCompareOp      = VkCompareOp.Less;
            pCreateInfo.pDepthStencilState = &depthState;

            VkPipelineColorBlendAttachmentState colourAttachment = new VkPipelineColorBlendAttachmentState();

            colourAttachment.colorWriteMask = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A;

            VkPipelineColorBlendStateCreateInfo colourState = VkPipelineColorBlendStateCreateInfo.New();

            colourState.pAttachments     = &colourAttachment;
            colourState.attachmentCount  = 1;
            pCreateInfo.pColorBlendState = &colourState;

            VkDynamicState[] dynamicStates = new VkDynamicState[2];
            dynamicStates[0] = VkDynamicState.Viewport;
            dynamicStates[1] = VkDynamicState.Scissor;

            VkPipelineDynamicStateCreateInfo dynamicState = VkPipelineDynamicStateCreateInfo.New();

            dynamicState.dynamicStateCount = (uint)dynamicStates.Length;

            fixed(VkDynamicState *ptr = &(dynamicStates[0]))
            dynamicState.pDynamicStates = ptr;

            pCreateInfo.pDynamicState = &dynamicState;

            this.pipelineLayout    = CreatePipelineLayout(device, desclayout);
            pCreateInfo.layout     = this.pipelineLayout;
            pCreateInfo.renderPass = renderPass;
            pCreateInfo.subpass    = 0;


            VkPipeline pipeline = VkPipeline.Null;

            Assert(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pCreateInfo, null, &pipeline));
            this.pipeline = pipeline;
        }