Exemplo n.º 1
0
        public SpecializationInfo(params SpecializationConstant[] constants)
        {
            uint offset = 0;

            entries = new VkSpecializationMapEntry[constants.Length];
            for (int i = 0; i < constants.Length; i++)
            {
                entries[i] = new VkSpecializationMapEntry {
                    constantID = constants[i].id, offset = offset, size = (UIntPtr)constants[i].Size
                };
                offset += constants[i].Size;
            }
            int totSize = (int)offset;

            offset = 0;
            pData  = Marshal.AllocHGlobal(totSize);
            IntPtr curPtr = pData;

            foreach (SpecializationConstant sc in constants)
            {
                sc.WriteTo(curPtr);
                curPtr += (int)sc.Size;
            }

            infos = new VkSpecializationInfo {
                mapEntryCount = (uint)constants.Length,
                pMapEntries   = entries.Pin(),
                pData         = pData,
                dataSize      = (UIntPtr)totSize
            };
            InfosPtr = infos.Pin();
        }
Exemplo n.º 2
0
        public void Build(int deviceIndex)
        {
            if (!locked)
            {
                unsafe
                {
                    var memHndl  = SpecializationData.Pin();
                    var specData = new VkSpecializationInfo()
                    {
                        mapEntryCount = (uint)SpecializationData.Length,
                        dataSize      = (uint)SpecializationData.Length * sizeof(int),
                        pMapEntries   = Shader.Specialize(),
                        pData         = (IntPtr)memHndl.Pointer
                    };
                    var specData_ptr = specData.Pointer();

                    var creatInfo = new VkComputePipelineCreateInfo()
                    {
                        sType = VkStructureType.StructureTypeComputePipelineCreateInfo,
                        stage = new VkPipelineShaderStageCreateInfo()
                        {
                            sType  = VkStructureType.StructureTypePipelineShaderStageCreateInfo,
                            stage  = (VkShaderStageFlags)Shader.ShaderType,
                            module = Shader.ids[deviceIndex],
                            pName  = "main",
                            pSpecializationInfo = specData_ptr
                        },
                        layout = PipelineLayout.hndl,
                    };

                    IntPtr pipeline_l = IntPtr.Zero;
                    if (vkCreateComputePipelines(GraphicsDevice.GetDeviceInfo(deviceIndex).Device, IntPtr.Zero, 1, creatInfo.Pointer(), null, &pipeline_l) != VkResult.Success)
                    {
                        throw new Exception("Failed to create compute pipeline.");
                    }
                    hndl = pipeline_l;

                    if (GraphicsDevice.EnableValidation)
                    {
                        var objName = new VkDebugUtilsObjectNameInfoEXT()
                        {
                            sType        = VkStructureType.StructureTypeDebugUtilsObjectNameInfoExt,
                            pObjectName  = Name,
                            objectType   = VkObjectType.ObjectTypePipeline,
                            objectHandle = (ulong)hndl
                        };
                        GraphicsDevice.SetDebugUtilsObjectNameEXT(GraphicsDevice.GetDeviceInfo(deviceIndex).Device, objName.Pointer());
                    }

                    devID  = deviceIndex;
                    locked = true;
                }
            }
            else
            {
                throw new Exception("Pipeline is locked.");
            }
        }
        internal IntPtr GetNative(DisposableList <IDisposable> marshalled)
        {
            var entriesMarshalled = new MarshalledArray <VkSpecializationMapEntry>(mapEntries);
            var dataMarshalled    = new PinnedArray <byte>(data);

            marshalled.Add(entriesMarshalled);
            marshalled.Add(dataMarshalled);

            var info = new VkSpecializationInfo();

            info.mapEntryCount = (uint)entriesMarshalled.Count;
            info.pMapEntries   = entriesMarshalled.Address;
            info.dataSize      = (uint)dataMarshalled.Count;
            info.pData         = dataMarshalled.Address;

            var infoMarshalled = new Marshalled <VkSpecializationInfo>(info);

            marshalled.Add(infoMarshalled);

            return(infoMarshalled.Address);
        }
        void preparePipelines()
        {
            VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
                Initializers.pipelineInputAssemblyStateCreateInfo(
                    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
                    0,
                    False);

            VkPipelineRasterizationStateCreateInfo rasterizationState =
                Initializers.pipelineRasterizationStateCreateInfo(
                    VK_POLYGON_MODE_FILL,
                    VK_CULL_MODE_NONE,
                    VK_FRONT_FACE_CLOCKWISE,
                    0);

            VkPipelineColorBlendAttachmentState blendAttachmentState =
                Initializers.pipelineColorBlendAttachmentState(
                    0xf,
                    False);

            VkPipelineColorBlendStateCreateInfo colorBlendState =
                Initializers.pipelineColorBlendStateCreateInfo(
                    1,
                    &blendAttachmentState);

            VkPipelineDepthStencilStateCreateInfo depthStencilState =
                Initializers.pipelineDepthStencilStateCreateInfo(
                    True,
                    True,
                    VK_COMPARE_OP_LESS_OR_EQUAL);

            VkPipelineViewportStateCreateInfo viewportState =
                Initializers.pipelineViewportStateCreateInfo(1, 1, 0);

            VkPipelineMultisampleStateCreateInfo multisampleState =
                Initializers.pipelineMultisampleStateCreateInfo(
                    VK_SAMPLE_COUNT_1_BIT,
                    0);

            FixedArray3 <VkDynamicState> dynamicStateEnables = new FixedArray3 <VkDynamicState>(
                VK_DYNAMIC_STATE_VIEWPORT,
                VK_DYNAMIC_STATE_SCISSOR,
                VK_DYNAMIC_STATE_LINE_WIDTH);

            VkPipelineDynamicStateCreateInfo dynamicState =
                Initializers.pipelineDynamicStateCreateInfo(
                    &dynamicStateEnables.First,
                    dynamicStateEnables.Count,
                    0);

            FixedArray2 <VkPipelineShaderStageCreateInfo> shaderStages = new FixedArray2 <VkPipelineShaderStageCreateInfo>();

            VkGraphicsPipelineCreateInfo pipelineCreateInfo =
                Initializers.pipelineCreateInfo(
                    pipelineLayout,
                    renderPass,
                    0);

            var vis = vertices_inputState;

            pipelineCreateInfo.pVertexInputState   = &vis;
            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             = &shaderStages.First;

            // Prepare specialization data

            SpecializationData specializationData = SpecializationData.Default;

            // Each shader constant of a shader stage corresponds to one map entry
            FixedArray2 <VkSpecializationMapEntry> specializationMapEntries = new FixedArray2 <VkSpecializationMapEntry>();

            // Shader bindings based on specialization constants are marked by the new "constant_id" layout qualifier:
            //	layout (constant_id = 0) const int LIGHTING_MODEL = 0;
            //	layout (constant_id = 1) const float PARAM_TOON_DESATURATION = 0.0f;

            // Map entry for the lighting model to be used by the fragment shader
            specializationMapEntries.First.constantID = 0;
            specializationMapEntries.First.size       = (UIntPtr)sizeof(uint);
            specializationMapEntries.First.offset     = 0;

            // Map entry for the toon shader parameter
            specializationMapEntries.Second.constantID = 1;
            specializationMapEntries.Second.size       = (UIntPtr)sizeof(float);
            specializationMapEntries.Second.offset     = (sizeof(uint));

            // Prepare specialization info block for the shader stage
            VkSpecializationInfo specializationInfo = new VkSpecializationInfo();

            specializationInfo.dataSize      = (UIntPtr)sizeof(SpecializationData);
            specializationInfo.mapEntryCount = specializationMapEntries.Count;
            specializationInfo.pMapEntries   = &specializationMapEntries.First;
            specializationInfo.pData         = &specializationData;

            // Create pipelines
            // All pipelines will use the same "uber" shader and specialization constants to change branching and parameters of that shader
            shaderStages.First  = loadShader(getAssetPath() + "shaders/specializationconstants/uber.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
            shaderStages.Second = loadShader(getAssetPath() + "shaders/specializationconstants/uber.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
            // Specialization info is assigned is part of the shader stage (modul) and must be set after creating the module and before creating the pipeline
            shaderStages.Second.pSpecializationInfo = &specializationInfo;

            // Solid phong shading
            specializationData.lightingModel = 0;

            Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_phong));

            // Phong and textured
            specializationData.lightingModel = 1;

            Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_toon));

            // Textured discard
            specializationData.lightingModel = 2;

            Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_textured));
        }
Exemplo n.º 5
0
        public void Build(int deviceIndex)
        {
            if (!locked)
            {
                unsafe
                {
                    //create pipeline shader stages
                    var shaderStages                   = new VkPipelineShaderStageCreateInfo[Shaders.Length];
                    var shaderSpecializations          = new ManagedPtr <VkSpecializationInfo> [Shaders.Length];
                    var shaderSpecializationBufferPtrs = new MemoryHandle[Shaders.Length];
                    for (int i = 0; i < shaderStages.Length; i++)
                    {
                        if (SpecializationData != null)
                        {
                            shaderSpecializationBufferPtrs[i] = SpecializationData[i].Pin();

                            shaderSpecializations[i] = new VkSpecializationInfo()
                            {
                                mapEntryCount = (uint)SpecializationData[i].Length,
                                pMapEntries   = Shaders[i].Specialize(),
                                dataSize      = (uint)SpecializationData[i].Length * sizeof(int),
                                pData         = (IntPtr)shaderSpecializationBufferPtrs[i].Pointer
                            }.Pointer();
                        }

                        shaderStages[i].sType  = VkStructureType.StructureTypePipelineShaderStageCreateInfo;
                        shaderStages[i].stage  = (VkShaderStageFlags)Shaders[i].ShaderType;
                        shaderStages[i].module = Shaders[i].ids[deviceIndex];
                        shaderStages[i].pName  = "main";
                        shaderStages[i].pSpecializationInfo = shaderSpecializations[i] != null ? shaderSpecializations[i] : IntPtr.Zero;
                    }
                    var shaderStages_ptr = shaderStages.Pointer();

                    //VkPipelineVertexInputStateCreateInfo - dummy, engine doesn't support fix function vertex input
                    var vertexInputInfo = new VkPipelineVertexInputStateCreateInfo()
                    {
                        sType = VkStructureType.StructureTypePipelineVertexInputStateCreateInfo,
                        vertexBindingDescriptionCount   = 0,
                        vertexAttributeDescriptionCount = 0,
                    };
                    var vertexInputInfo_ptr = vertexInputInfo.Pointer();

                    //VkPipelineInputAssemblyStateCreateInfo - state
                    var inputAssembly = new VkPipelineInputAssemblyStateCreateInfo()
                    {
                        sType    = VkStructureType.StructureTypePipelineInputAssemblyStateCreateInfo,
                        topology = (VkPrimitiveTopology)Topology,
                        primitiveRestartEnable = false,
                    };
                    var inputAssembly_ptr = inputAssembly.Pointer();

                    //VkPipelineViewportStateCreateInfo - dynamic state, no scissor
                    var viewport = new VkViewport()
                    {
                        x        = ViewportX,
                        y        = ViewportY,
                        width    = ViewportWidth,
                        height   = ViewportHeight,
                        minDepth = ViewportMinDepth,
                        maxDepth = ViewportMaxDepth,
                    };

                    var scissor = new VkRect2D()
                    {
                        offset = new VkOffset2D()
                        {
                            x = (int)ViewportX,
                            y = (int)ViewportY
                        },
                        extent = new VkExtent2D()
                        {
                            width  = ViewportWidth,
                            height = ViewportHeight
                        }
                    };

                    var viewport_ptr       = viewport.Pointer();
                    var scissor_ptr        = scissor.Pointer();
                    var viewportCreateInfo = new VkPipelineViewportStateCreateInfo()
                    {
                        sType         = VkStructureType.StructureTypePipelineViewportStateCreateInfo,
                        viewportCount = 1,
                        pViewports    = viewport_ptr,
                        scissorCount  = 1,
                        pScissors     = scissor_ptr
                    };
                    var viewportCreateInfo_ptr = viewportCreateInfo.Pointer();

                    //VkPipelineRasterizationStateCreateInfo - state
                    var rasterizer = new VkPipelineRasterizationStateCreateInfo()
                    {
                        sType                   = VkStructureType.StructureTypePipelineRasterizationStateCreateInfo,
                        depthClampEnable        = DepthClamp,
                        rasterizerDiscardEnable = RasterizerDiscard,
                        polygonMode             = (VkPolygonMode)Fill,
                        lineWidth               = LineWidth,
                        cullMode                = (VkCullModeFlags)CullMode,
                        frontFace               = VkFrontFace.FrontFaceCounterClockwise, //OpenGL default
                        depthBiasEnable         = false,
                        depthBiasConstantFactor = 0,
                        depthBiasClamp          = 0,
                        depthBiasSlopeFactor    = 0,
                    };
                    var rasterizer_ptr = rasterizer.Pointer();

                    //VkPipelineMultisampleStateCreateInfo - don't support for now
                    var multisampling = new VkPipelineMultisampleStateCreateInfo()
                    {
                        sType = VkStructureType.StructureTypePipelineMultisampleStateCreateInfo,
                        sampleShadingEnable   = false,
                        rasterizationSamples  = VkSampleCountFlags.SampleCount1Bit,
                        minSampleShading      = 1,
                        pSampleMask           = null,
                        alphaToCoverageEnable = false,
                        alphaToOneEnable      = false
                    };
                    var multisampling_ptr = multisampling.Pointer();

                    //VkPipelineDepthStencilStateCreateInfo - state
                    var depthStencil = new VkPipelineDepthStencilStateCreateInfo()
                    {
                        sType                 = VkStructureType.StructureTypePipelineDepthStencilStateCreateInfo,
                        depthTestEnable       = true,
                        depthCompareOp        = (VkCompareOp)DepthTest,
                        depthWriteEnable      = DepthWrite,
                        depthBoundsTestEnable = false,
                        stencilTestEnable     = false,
                        maxDepthBounds        = ViewportMaxDepth,
                        minDepthBounds        = ViewportMinDepth,
                    };
                    var depthStencil_ptr = depthStencil.Pointer();


                    //VkPipelineColorBlendStateCreateInfo - state
                    var colorBlendStates = new VkPipelineColorBlendAttachmentState[RenderPass.ColorAttachments == null ? 0 : RenderPass.ColorAttachments.Length];
                    for (int i = 0; i < colorBlendStates.Length; i++)
                    {
                        colorBlendStates[i] = new VkPipelineColorBlendAttachmentState()
                        {
                            colorWriteMask = VkColorComponentFlags.ColorComponentRBit | VkColorComponentFlags.ColorComponentGBit | VkColorComponentFlags.ColorComponentBBit | VkColorComponentFlags.ColorComponentABit,
                            blendEnable    = false,
                        };
                    }
                    var colorBlendStates_ptr = colorBlendStates.Pointer();

                    var colorBlend = new VkPipelineColorBlendStateCreateInfo()
                    {
                        sType           = VkStructureType.StructureTypePipelineColorBlendStateCreateInfo,
                        logicOpEnable   = false,
                        logicOp         = VkLogicOp.LogicOpCopy,
                        attachmentCount = (uint)colorBlendStates.Length,
                        pAttachments    = colorBlendStates_ptr,
                    };
                    colorBlend.blendConstants[0] = 0;
                    colorBlend.blendConstants[1] = 0;
                    colorBlend.blendConstants[2] = 0;
                    colorBlend.blendConstants[3] = 0;
                    var colorBlend_ptr = colorBlend.Pointer();

                    var dynamicStates = stackalloc VkDynamicState[]
                    {
                        VkDynamicState.DynamicStateViewport
                    };

                    var dynamicState = new VkPipelineDynamicStateCreateInfo()
                    {
                        sType             = VkStructureType.StructureTypePipelineDynamicStateCreateInfo,
                        dynamicStateCount = ViewportDynamic ? 1u : 0u,
                        pDynamicStates    = dynamicStates
                    };
                    var dynamicState_ptr = dynamicState.Pointer();

                    //Setup graphics pipeline
                    var pipelineInfo = new VkGraphicsPipelineCreateInfo()
                    {
                        sType               = VkStructureType.StructureTypeGraphicsPipelineCreateInfo,
                        stageCount          = (uint)shaderStages.Length,
                        pStages             = shaderStages_ptr,
                        pVertexInputState   = vertexInputInfo_ptr,
                        pInputAssemblyState = inputAssembly_ptr,
                        pViewportState      = viewportCreateInfo_ptr,
                        pRasterizationState = rasterizer_ptr,
                        pMultisampleState   = multisampling_ptr,
                        pDepthStencilState  = depthStencil_ptr,
                        pColorBlendState    = colorBlend_ptr,
                        pDynamicState       = dynamicState_ptr,
                        layout              = PipelineLayout.hndl,
                        renderPass          = RenderPass.hndl,
                        subpass             = 0,
                        basePipelineHandle  = IntPtr.Zero,
                        basePipelineIndex   = -1,
                    };

                    IntPtr pipeline_l = IntPtr.Zero;
                    if (vkCreateGraphicsPipelines(GraphicsDevice.GetDeviceInfo(deviceIndex).Device, IntPtr.Zero, 1, pipelineInfo.Pointer(), null, &pipeline_l) != VkResult.Success)
                    {
                        throw new Exception("Failed to create graphics pipeline.");
                    }
                    hndl = pipeline_l;

                    if (GraphicsDevice.EnableValidation)
                    {
                        var objName = new VkDebugUtilsObjectNameInfoEXT()
                        {
                            sType        = VkStructureType.StructureTypeDebugUtilsObjectNameInfoExt,
                            pObjectName  = Name,
                            objectType   = VkObjectType.ObjectTypePipeline,
                            objectHandle = (ulong)hndl
                        };
                        GraphicsDevice.SetDebugUtilsObjectNameEXT(GraphicsDevice.GetDeviceInfo(deviceIndex).Device, objName.Pointer());
                    }

                    devID  = deviceIndex;
                    locked = true;
                }
            }
            else
            {
                throw new Exception("Pipeline is locked.");
            }
        }