예제 #1
0
        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;
        }
예제 #2
0
        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));
            }
        }