public Triangle() { InitializeComponent(); InitializeVulkan(); _Bitmap = new Bitmap(640, 480); _Framebuffer = new Framebuffer(_Device, 640, 480); VkPipelineLayout dummyLayout = _Device.CreatePipelineLayout(VkPipelineLayoutCreateFlag.NONE, null, null); _VertexShader = _Device.CreateShaderModule(VkShaderModuleCreateFlag.NONE, System.IO.File.ReadAllBytes("./Shaders/vertexShader.spv")); _FramgemtShader = _Device.CreateShaderModule(VkShaderModuleCreateFlag.NONE, System.IO.File.ReadAllBytes("./Shaders/fragmentShader.spv")); _GraphicsPipeline = new Pipeline(_Framebuffer, dummyLayout, _VertexShader, "main", _FramgemtShader, "main"); // Finally we will need a fence for our submission in order to wait on it _Fence = _Device.CreateFence(VkFenceCreateFlag.NONE); // VkBuffer indexBuffer = _Device.CreateBuffer(0, 3 * sizeof(Int32), VkBufferUsageFlag.VK_BUFFER_USAGE_INDEX_BUFFER, VkSharingMode.VK_SHARING_MODE_CONCURRENT, new VkQueueFamilyProperties[] { _Queue.Family }); // VkBuffer vertexBuffer = _Device.CreateBuffer(0, 3 * sizeof(float), VkBufferUsageFlag.VK_BUFFER_USAGE_VERTEX_BUFFER, VkSharingMode.VK_SHARING_MODE_CONCURRENT, new VkQueueFamilyProperties[] { _Queue.Family }); // Now we need to create a command buffer and we will fill it with a single command: // Fill the image with the color (0.1f, 0.75f, 1.0f, 1.0f) which is a Sky blue. VkClearValue.VkClearColorValue.Float color = new VkClearValue.VkClearColorValue.Float(); color.float32[0] = 0.1f; color.float32[1] = 0.75f; color.float32[2] = 1.0f; color.float32[3] = 1.0f; VkCommandPool Pool = _Device.CreateCommandPool(VkCommandPoolCreateFlag.NONE, _Queue.Family); _CommandBuffer = Pool.AllocateCommandBuffer(VkCommandBufferLevel.VK_COMMAND_BUFFER_LEVEL_PRIMARY); _CommandBuffer.Begin(VkCommandBufferUsageFlag.NONE); _CommandBuffer.CmdBeginRenderPass(_Framebuffer.RenderPass, new VkRect2D(0, 0, (uint)640, (uint)480), _Framebuffer.GetFramebuffer(), new VkClearValue[] { color }, VkSubpassContents.VK_SUBPASS_CONTENTS_INLINE); _GraphicsPipeline.BindPipeline(_CommandBuffer); _CommandBuffer.CmdDraw(3, 1, 0, 0); _CommandBuffer.CmdEndRenderPass(); _CommandBuffer.cmdCopyImageToBuffer(_Framebuffer.FrameBufferColor, VkImageLayout.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, _Framebuffer._TransferBuffer, new VkBufferImageCopy[] { new VkBufferImageCopy() { bufferImageHeight = (uint)_Framebuffer.Height, bufferOffset = 0, bufferRowLength = (uint)_Framebuffer.Width, imageExtent = new VkExtent3D() { depth = 1, width = (uint)_Framebuffer.Width, height = (uint)_Framebuffer.Height }, imageSubresource = new VkImageSubresourceLayers() { aspectMask = VkImageAspectFlag.VK_IMAGE_ASPECT_COLOR_BIT, baseArrayLayer = 0, layerCount = 1, mipLevel = 0 } } }); _CommandBuffer.End(); }
public Pipeline(Framebuffer Framebuffer, VkPipelineLayout PipelineLayout, VkShaderModule VertexShader, string VertexShaderEntryPoint, VkShaderModule FragmentShader, string FragmentShaderEntryPoint) { VkPipelineVertexInputStateCreateInfo vertexInputInfo = new VkPipelineVertexInputStateCreateInfo(); vertexInputInfo.flags = VkPipelineVertexInputStateCreateFlag.NONE; vertexInputInfo.vertexAttributeDescriptions = null; vertexInputInfo.vertexBindingDescriptions = null; VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = new VkPipelineInputAssemblyStateCreateInfo(); inputAssemblyInfo.flags = VkPipelineInputAssemblyStateCreateFlag.NONE; inputAssemblyInfo.primitiveRestartEnable = false; inputAssemblyInfo.topology = VkPrimitiveTopology.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; VkPipelineViewportStateCreateInfo viewportInfo = new VkPipelineViewportStateCreateInfo(); viewportInfo.flags = VkPipelineViewportStateCreateFlag.NONE; viewportInfo.scissors = new VkRect2D[] { new VkRect2D(0, 0, (uint)Framebuffer.Width, (uint)Framebuffer.Height) }; viewportInfo.viewports = new VkViewport[] { new VkViewport(0.0f, 0.0f, (float)(Framebuffer.Width), (float)(Framebuffer.Height), 0.0f, 1.0f) }; VkPipelineRasterizationStateCreateInfo rasterizationInfo = new VkPipelineRasterizationStateCreateInfo(); rasterizationInfo.flags = VkPipelineRasterizationStateCreateFlag.NONE; rasterizationInfo.depthClampEnable = false; rasterizationInfo.rasterizerDiscardEnable = false; rasterizationInfo.polygonMode = VkPolygonMode.VK_POLYGON_MODE_FILL; rasterizationInfo.lineWidth = 1.0f; rasterizationInfo.cullMode = VkCullModeFlag.VK_CULL_MODE_BACK; rasterizationInfo.frontFace = VkFrontFace.VK_FRONT_FACE_CLOCKWISE; rasterizationInfo.depthBiasEnable = false; VkPipelineMultisampleStateCreateInfo multisamplingInfo = new VkPipelineMultisampleStateCreateInfo(); multisamplingInfo.flags = VkPipelineMultisampleStateCreateFlag.NONE; multisamplingInfo.sampleShadingEnable = false; multisamplingInfo.rasterizationSamples = VkSampleCountFlag.VK_SAMPLE_COUNT_1; VkPipelineColorBlendStateCreateInfo colorBlendingInfo = new VkPipelineColorBlendStateCreateInfo(); colorBlendingInfo.flags = VkPipelineColorBlendStateCreateFlag.NONE; colorBlendingInfo.logicOpEnable = false; colorBlendingInfo.logicOp = VkLogicOp.VK_LOGIC_OP_COPY; colorBlendingInfo.attachments = new VkPipelineColorBlendAttachmentState[] { new VkPipelineColorBlendAttachmentState() { colorWriteMask = VkColorComponentFlag.VK_COLOR_COMPONENT_R | VkColorComponentFlag.VK_COLOR_COMPONENT_G | VkColorComponentFlag.VK_COLOR_COMPONENT_B | VkColorComponentFlag.VK_COLOR_COMPONENT_A, blendEnable = 0 } }; _Pipeline = Framebuffer.Device.CreateGraphicsPipeline(null, VkPipelineCreateFlags.NONE, new VkPipelineShaderStageCreateInfo[] { new VkPipelineShaderStageCreateInfo(VertexShader, VertexShaderEntryPoint, VkShaderStageFlag.VK_SHADER_STAGE_VERTEX), new VkPipelineShaderStageCreateInfo(FragmentShader, FragmentShaderEntryPoint, VkShaderStageFlag.VK_SHADER_STAGE_FRAGMENT) }, vertexInputInfo, inputAssemblyInfo, null, viewportInfo, rasterizationInfo, multisamplingInfo, null, colorBlendingInfo, null, PipelineLayout, Framebuffer.RenderPass, 0, null, -1 ); }