void generateQuad() { // Setup vertices for a single uv-mapped quad Vector3 defaultColor = new Vector3(1, 1, 1); Vector3 defaultNormal = new Vector3(0, 0, 1); FixedArray4<Vertex> vertexBuffer = new FixedArray4<Vertex>( new Vertex { pos = new Vector3(1, 1, 0), uv = new Vector2(1, 1), col = defaultColor, normal = defaultNormal }, new Vertex { pos = new Vector3(0, 1, 0), uv = new Vector2(0, 1), col = defaultColor, normal = defaultNormal }, new Vertex { pos = new Vector3(0, 0, 0), uv = new Vector2(0, 0), col = defaultColor, normal = defaultNormal }, new Vertex { pos = new Vector3(1, 0, 0), uv = new Vector2(1, 0), col = defaultColor, normal = defaultNormal }); Util.CheckResult(vulkanDevice.createBuffer( VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, (ulong)(vertexBuffer.Count * sizeof(Vertex)), out models_quad.vertices.buffer, out models_quad.vertices.memory, &vertexBuffer.First)); // Setup indices FixedArray6<uint> indexBuffer = new FixedArray6<uint>(0, 1, 2, 2, 3, 0); models_quad.indexCount = indexBuffer.Count; Util.CheckResult(vulkanDevice.createBuffer( VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexBuffer.Count * sizeof(uint), out models_quad.indices.buffer, out models_quad.indices.memory, &indexBuffer.First)); models_quad.device = device; }
void preparePipelines() { VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = Initializers.pipelineInputAssemblyStateCreateInfo( VkPrimitiveTopology.TriangleList, 0, False); VkPipelineRasterizationStateCreateInfo rasterizationState = Initializers.pipelineRasterizationStateCreateInfo( VkPolygonMode.Fill, VkCullModeFlags.Back, VkFrontFace.Clockwise, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = Initializers.pipelineColorBlendAttachmentState( (VkColorComponentFlags)0xf, False); VkPipelineColorBlendStateCreateInfo colorBlendState = Initializers.pipelineColorBlendStateCreateInfo( 1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = Initializers.pipelineDepthStencilStateCreateInfo( True, True, VkCompareOp.LessOrEqual); VkPipelineViewportStateCreateInfo viewportState = Initializers.pipelineViewportStateCreateInfo(1, 1, 0); VkPipelineMultisampleStateCreateInfo multisampleState = Initializers.pipelineMultisampleStateCreateInfo(VkSampleCountFlags._1); FixedArray3 <VkDynamicState> dynamicStateEnables = new FixedArray3 <VkDynamicState>( VkDynamicState.Viewport, VkDynamicState.Scissor, VkDynamicState.LineWidth); VkPipelineDynamicStateCreateInfo dynamicState = Initializers.pipelineDynamicStateCreateInfo((VkDynamicState *)Unsafe.AsPointer(ref dynamicStateEnables), dynamicStateEnables.Count); VkGraphicsPipelineCreateInfo pipelineCreateInfo = Initializers.pipelineCreateInfo(pipelineLayout, RenderPass); FixedArray2 <VkPipelineShaderStageCreateInfo> shaderStages = new FixedArray2 <VkPipelineShaderStageCreateInfo>(); shaderStages.First = loadShader(getAssetPath() + "shaders/pipelines/phong.vert.spv", VkShaderStageFlags.Vertex); shaderStages.Second = loadShader(getAssetPath() + "shaders/pipelines/phong.frag.spv", VkShaderStageFlags.Fragment); pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; pipelineCreateInfo.pRasterizationState = &rasterizationState; pipelineCreateInfo.pColorBlendState = &colorBlendState; pipelineCreateInfo.pMultisampleState = &multisampleState; pipelineCreateInfo.pViewportState = &viewportState; pipelineCreateInfo.pDepthStencilState = &depthStencilState; pipelineCreateInfo.pDynamicState = &dynamicState; pipelineCreateInfo.stageCount = shaderStages.Count; pipelineCreateInfo.pStages = (VkPipelineShaderStageCreateInfo *)Unsafe.AsPointer(ref shaderStages); // Shared vertex bindings and attributes used by all pipelines // Binding description VkVertexInputBindingDescription vertexInputBindings = Initializers.vertexInputBindingDescription(VERTEX_BUFFER_BIND_ID, vertexLayout.GetStride(), VkVertexInputRate.Vertex); // Attribute descriptions FixedArray4 <VkVertexInputAttributeDescription> vertexInputAttributes = new FixedArray4 <VkVertexInputAttributeDescription> { First = Initializers.vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 0, VkFormat.R32g32b32Sfloat, 0), // Location 0: Position Second = Initializers.vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 1, VkFormat.R32g32b32Sfloat, sizeof(float) * 3), // Location 1: Color Third = Initializers.vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 2, VkFormat.R32g32Sfloat, sizeof(float) * 6), // Location 2 : Texture coordinates Fourth = Initializers.vertexInputAttributeDescription(VERTEX_BUFFER_BIND_ID, 3, VkFormat.R32g32b32Sfloat, sizeof(float) * 8), // Location 3 : Normal }; VkPipelineVertexInputStateCreateInfo vertexInputState = VkPipelineVertexInputStateCreateInfo.New(); vertexInputState.vertexBindingDescriptionCount = 1; vertexInputState.pVertexBindingDescriptions = &vertexInputBindings; vertexInputState.vertexAttributeDescriptionCount = vertexInputAttributes.Count; vertexInputState.pVertexAttributeDescriptions = (VkVertexInputAttributeDescription *)Unsafe.AsPointer(ref vertexInputAttributes); pipelineCreateInfo.pVertexInputState = &vertexInputState; // Create the graphics pipeline state objects // We are using this pipeline as the base for the other pipelines (derivatives) // Pipeline derivatives can be used for pipelines that share most of their state // Depending on the implementation this may result in better performance for pipeline // switchting and faster creation time pipelineCreateInfo.flags = VkPipelineCreateFlags.AllowDerivatives; // Textured pipeline // Phong shading pipeline shaderStages.First = loadShader(getAssetPath() + "shaders/pipelines/phong.vert.spv", VkShaderStageFlags.Vertex); shaderStages.Second = loadShader(getAssetPath() + "shaders/pipelines/phong.frag.spv", VkShaderStageFlags.Fragment); Util.CheckResult(vkCreateGraphicsPipelines(Device, PipelineCache, 1, ref pipelineCreateInfo, null, out pipelines_phong)); // All pipelines created after the base pipeline will be derivatives pipelineCreateInfo.flags = VkPipelineCreateFlags.Derivative; // Base pipeline will be our first created pipeline pipelineCreateInfo.basePipelineHandle = pipelines_phong; // It's only allowed to either use a handle or index for the base pipeline // As we use the handle, we must set the index to -1 (see section 9.5 of the specification) pipelineCreateInfo.basePipelineIndex = -1; // Toon shading pipeline shaderStages.First = loadShader(getAssetPath() + "shaders/pipelines/toon.vert.spv", VkShaderStageFlags.Vertex); shaderStages.Second = loadShader(getAssetPath() + "shaders/pipelines/toon.frag.spv", VkShaderStageFlags.Fragment); Util.CheckResult(vkCreateGraphicsPipelines(Device, PipelineCache, 1, ref pipelineCreateInfo, null, out pipelines_toon)); // Pipeline for wire frame rendering // Non solid rendering is not a mandatory Vulkan feature if (DeviceFeatures.fillModeNonSolid != 0) { rasterizationState.polygonMode = VkPolygonMode.Line; shaderStages.First = loadShader(getAssetPath() + "shaders/pipelines/wireframe.vert.spv", VkShaderStageFlags.Vertex); shaderStages.Second = loadShader(getAssetPath() + "shaders/pipelines/wireframe.frag.spv", VkShaderStageFlags.Fragment); Util.CheckResult(vkCreateGraphicsPipelines(Device, PipelineCache, 1, ref pipelineCreateInfo, null, out pipelines_wireframe)); } }