Ejemplo n.º 1
0
        //[HandleProcessCorruptedStateExceptionsAttribute, SecurityCriticalAttribute]
        private unsafe void Recreate()
        {
            errorDuringCreate = false;

            if (Description.RootSignature == null)
            {
                return;
            }

            VkPipelineShaderStageCreateInfo[] stages;

            // create render pass
            bool hasDepthStencilAttachment = Description.Output.DepthStencilFormat != PixelFormat.None;

            var renderTargetCount = Description.Output.RenderTargetCount;

            var attachmentCount = renderTargetCount;

            if (hasDepthStencilAttachment)
            {
                attachmentCount++;
            }

            var attachments = new VkAttachmentDescription[attachmentCount];
            var colorAttachmentReferences = new VkAttachmentReference[renderTargetCount];

            fixed(PixelFormat *renderTargetFormat = &Description.Output.RenderTargetFormat0)
            fixed(BlendStateRenderTargetDescription * blendDescription = &Description.BlendState.RenderTarget0)
            {
                for (int i = 0; i < renderTargetCount; i++)
                {
                    var currentBlendDesc = Description.BlendState.IndependentBlendEnable ? (blendDescription + i) : blendDescription;

                    attachments[i] = new VkAttachmentDescription
                    {
                        format         = VulkanConvertExtensions.ConvertPixelFormat(*(renderTargetFormat + i)),
                        samples        = VkSampleCountFlags.Count1,
                        loadOp         = currentBlendDesc->BlendEnable ? VkAttachmentLoadOp.Load : VkAttachmentLoadOp.DontCare, // TODO VULKAN: Only if any destination blend?
                        storeOp        = VkAttachmentStoreOp.Store,
                        stencilLoadOp  = VkAttachmentLoadOp.DontCare,
                        stencilStoreOp = VkAttachmentStoreOp.DontCare,
                        initialLayout  = VkImageLayout.ColorAttachmentOptimal,
                        finalLayout    = VkImageLayout.ColorAttachmentOptimal,
                    };

                    colorAttachmentReferences[i] = new VkAttachmentReference
                    {
                        attachment = (uint)i,
                        layout     = VkImageLayout.ColorAttachmentOptimal,
                    };
                }
            }

            if (hasDepthStencilAttachment)
            {
                attachments[attachmentCount - 1] = new VkAttachmentDescription
                {
                    format         = Texture.GetFallbackDepthStencilFormat(GraphicsDevice, VulkanConvertExtensions.ConvertPixelFormat(Description.Output.DepthStencilFormat)),
                    samples        = VkSampleCountFlags.Count1,
                    loadOp         = VkAttachmentLoadOp.Load,     // TODO VULKAN: Only if depth read enabled?
                    storeOp        = VkAttachmentStoreOp.Store,   // TODO VULKAN: Only if depth write enabled?
                    stencilLoadOp  = VkAttachmentLoadOp.DontCare, // TODO VULKAN: Handle stencil
                    stencilStoreOp = VkAttachmentStoreOp.DontCare,
                    initialLayout  = VkImageLayout.DepthStencilAttachmentOptimal,
                    finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal,
                };
            }

            var depthAttachmentReference = new VkAttachmentReference
            {
                attachment = (uint)attachments.Length - 1,
                layout     = VkImageLayout.DepthStencilAttachmentOptimal,
            };

            var subpass = new VkSubpassDescription
            {
                pipelineBindPoint       = VkPipelineBindPoint.Graphics,
                colorAttachmentCount    = (uint)renderTargetCount,
                pColorAttachments       = colorAttachmentReferences.Length > 0 ? (VkAttachmentReference *)Core.Interop.Fixed(colorAttachmentReferences) : null,
                pDepthStencilAttachment = hasDepthStencilAttachment ? &depthAttachmentReference : null,
            };

            var renderPassCreateInfo = new VkRenderPassCreateInfo
            {
                sType           = VkStructureType.RenderPassCreateInfo,
                attachmentCount = (uint)attachmentCount,
                pAttachments    = attachments.Length > 0 ? (VkAttachmentDescription *)Core.Interop.Fixed(attachments) : null,
                subpassCount    = 1,
                pSubpasses      = &subpass,
            };

            // create pipeline layout
            // Remap descriptor set indices to those in the shader. This ordering generated by the ShaderCompiler
            var resourceGroups = Description.EffectBytecode.Reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList();

            ResourceGroupCount = resourceGroups.Count;

            var layouts = Description.RootSignature.EffectDescriptorSetReflection.Layouts;

            // Get binding indices used by the shader
            var destinationBindings = Description.EffectBytecode.Stages
                                      .SelectMany(x => BinarySerialization.Read <ShaderInputBytecode>(x.Data).ResourceBindings)
                                      .GroupBy(x => x.Key, x => x.Value)
                                      .ToDictionary(x => x.Key, x => x.First());

            var maxBindingIndex    = destinationBindings.Max(x => x.Value);
            var destinationEntries = new DescriptorSetLayoutBuilder.Entry[maxBindingIndex + 1];

            DescriptorBindingMapping = new List <DescriptorSetInfo>();

            for (int i = 0; i < resourceGroups.Count; i++)
            {
                var resourceGroupName = resourceGroups[i] == "Globals" ? Description.RootSignature.EffectDescriptorSetReflection.DefaultSetSlot : resourceGroups[i];
                var layoutIndex       = resourceGroups[i] == null ? 0 : layouts.FindIndex(x => x.Name == resourceGroupName);

                // Check if the resource group is used by the shader
                if (layoutIndex == -1)
                {
                    continue;
                }

                var sourceEntries = layouts[layoutIndex].Layout.Entries;

                for (int sourceBinding = 0; sourceBinding < sourceEntries.Count; sourceBinding++)
                {
                    var sourceEntry = sourceEntries[sourceBinding];

                    int destinationBinding;
                    if (destinationBindings.TryGetValue(sourceEntry.Key.Name, out destinationBinding))
                    {
                        destinationEntries[destinationBinding] = sourceEntry;

                        // No need to umpdate immutable samplers
                        if (sourceEntry.Class == EffectParameterClass.Sampler && sourceEntry.ImmutableSampler != null)
                        {
                            continue;
                        }

                        DescriptorBindingMapping.Add(new DescriptorSetInfo
                        {
                            SourceSet          = layoutIndex,
                            SourceBinding      = sourceBinding,
                            DestinationBinding = destinationBinding,
                            DescriptorType     = VulkanConvertExtensions.ConvertDescriptorType(sourceEntry.Class, sourceEntry.Type)
                        });
                    }
                }
            }

            // Create default sampler, used by texture and buffer loads
            destinationEntries[0] = new DescriptorSetLayoutBuilder.Entry
            {
                Class            = EffectParameterClass.Sampler,
                Type             = EffectParameterType.Sampler,
                ImmutableSampler = GraphicsDevice.SamplerStates.PointWrap,
                ArraySize        = 1,
            };

            // Create descriptor set layout
            NativeDescriptorSetLayout = DescriptorSetLayout.CreateNativeDescriptorSetLayout(GraphicsDevice, destinationEntries, out DescriptorTypeCounts);

            // Create pipeline layout
            var nativeDescriptorSetLayout = NativeDescriptorSetLayout;
            var pipelineLayoutCreateInfo  = new VkPipelineLayoutCreateInfo
            {
                sType          = VkStructureType.PipelineLayoutCreateInfo,
                setLayoutCount = 1,
                pSetLayouts    = &nativeDescriptorSetLayout,
            };

            // Create shader stages
            Dictionary <int, string> inputAttributeNames;

            // Note: important to pin this so that stages[x].Name is valid during this whole function
            void *defaultEntryPointData = Core.Interop.Fixed(defaultEntryPoint);

            stages = CreateShaderStages(Description, out inputAttributeNames);

            var inputAttributes     = new VkVertexInputAttributeDescription[Description.InputElements.Length];
            int inputAttributeCount = 0;
            var inputBindings       = new VkVertexInputBindingDescription[inputAttributes.Length];
            int inputBindingCount   = 0;

            for (int inputElementIndex = 0; inputElementIndex < inputAttributes.Length; inputElementIndex++)
            {
                var inputElement = Description.InputElements[inputElementIndex];
                var slotIndex    = inputElement.InputSlot;

                if (inputElement.InstanceDataStepRate > 1)
                {
                    throw new NotImplementedException();
                }

                VkFormat format;
                int      size;
                bool     isCompressed;
                VulkanConvertExtensions.ConvertPixelFormat(inputElement.Format, out format, out size, out isCompressed);

                var location = inputAttributeNames.FirstOrDefault(x => x.Value == inputElement.SemanticName && inputElement.SemanticIndex == 0 || x.Value == inputElement.SemanticName + inputElement.SemanticIndex);
                if (location.Value != null)
                {
                    inputAttributes[inputAttributeCount++] = new VkVertexInputAttributeDescription
                    {
                        format   = format,
                        offset   = (uint)inputElement.AlignedByteOffset,
                        binding  = (uint)inputElement.InputSlot,
                        location = (uint)location.Key
                    };
                }

                inputBindings[slotIndex].binding   = (uint)slotIndex;
                inputBindings[slotIndex].inputRate = inputElement.InputSlotClass == InputClassification.Vertex ? VkVertexInputRate.Vertex : VkVertexInputRate.Instance;

                // TODO VULKAN: This is currently an argument to Draw() overloads.
                if (inputBindings[slotIndex].stride < inputElement.AlignedByteOffset + size)
                {
                    inputBindings[slotIndex].stride = (uint)(inputElement.AlignedByteOffset + size);
                }

                if (inputElement.InputSlot >= inputBindingCount)
                {
                    inputBindingCount = inputElement.InputSlot + 1;
                }
            }

            var inputAssemblyState = new VkPipelineInputAssemblyStateCreateInfo
            {
                sType    = VkStructureType.PipelineInputAssemblyStateCreateInfo,
                topology = VulkanConvertExtensions.ConvertPrimitiveType(Description.PrimitiveType),
                primitiveRestartEnable = VulkanConvertExtensions.ConvertPrimitiveRestart(Description.PrimitiveType) ? (uint)1 : (uint)0,
            };

            // TODO VULKAN: Tessellation and multisampling
            var multisampleState = new VkPipelineMultisampleStateCreateInfo
            {
                sType = VkStructureType.PipelineMultisampleStateCreateInfo,
                rasterizationSamples = VkSampleCountFlags.Count1,
            };

            var rasterizationState = new VkPipelineRasterizationStateCreateInfo
            {
                sType                   = VkStructureType.PipelineRasterizationStateCreateInfo,
                cullMode                = VulkanConvertExtensions.ConvertCullMode(Description.RasterizerState.CullMode),
                frontFace               = Description.RasterizerState.FrontFaceCounterClockwise ? VkFrontFace.CounterClockwise : VkFrontFace.Clockwise,
                polygonMode             = VulkanConvertExtensions.ConvertFillMode(Description.RasterizerState.FillMode),
                depthBiasEnable         = 1, // TODO VULKAN
                depthBiasConstantFactor = Description.RasterizerState.DepthBias,
                depthBiasSlopeFactor    = Description.RasterizerState.SlopeScaleDepthBias,
                depthBiasClamp          = Description.RasterizerState.DepthBiasClamp,
                lineWidth               = 1.0f,
                depthClampEnable        = Description.RasterizerState.DepthClipEnable ? (uint)0 : (uint)1,
                rasterizerDiscardEnable = 0,
            };

            var depthStencilState = new VkPipelineDepthStencilStateCreateInfo
            {
                sType             = VkStructureType.PipelineDepthStencilStateCreateInfo,
                depthTestEnable   = Description.DepthStencilState.DepthBufferEnable ? (uint)1 : (uint)0,
                stencilTestEnable = Description.DepthStencilState.StencilEnable ? (uint)1 : (uint)0,
                depthWriteEnable  = Description.DepthStencilState.DepthBufferWriteEnable ? (uint)1 : (uint)0,

                minDepthBounds = 0.0f,
                maxDepthBounds = 1.0f,
                depthCompareOp = VulkanConvertExtensions.ConvertComparisonFunction(Description.DepthStencilState.DepthBufferFunction),
                front          =
                {
                    compareOp   = VulkanConvertExtensions.ConvertComparisonFunction(Description.DepthStencilState.FrontFace.StencilFunction),
                    depthFailOp = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.FrontFace.StencilDepthBufferFail),
                    failOp      = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.FrontFace.StencilFail),
                    passOp      = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.FrontFace.StencilPass),
                    compareMask = Description.DepthStencilState.StencilMask,
                    writeMask   = Description.DepthStencilState.StencilWriteMask
                },
                back =
                {
                    compareOp   = VulkanConvertExtensions.ConvertComparisonFunction(Description.DepthStencilState.BackFace.StencilFunction),
                    depthFailOp = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.BackFace.StencilDepthBufferFail),
                    failOp      = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.BackFace.StencilFail),
                    passOp      = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.BackFace.StencilPass),
                    compareMask = Description.DepthStencilState.StencilMask,
                    writeMask   = Description.DepthStencilState.StencilWriteMask
                }
            };

            var description = Description.BlendState;

            var colorBlendAttachments = new VkPipelineColorBlendAttachmentState[renderTargetCount];

            var renderTargetBlendState = &description.RenderTarget0;

            for (int i = 0; i < renderTargetCount; i++)
            {
                colorBlendAttachments[i] = new VkPipelineColorBlendAttachmentState
                {
                    blendEnable         = renderTargetBlendState->BlendEnable ? (uint)1 : (uint)0,
                    alphaBlendOp        = VulkanConvertExtensions.ConvertBlendFunction(renderTargetBlendState->AlphaBlendFunction),
                    colorBlendOp        = VulkanConvertExtensions.ConvertBlendFunction(renderTargetBlendState->ColorBlendFunction),
                    dstAlphaBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->AlphaDestinationBlend),
                    dstColorBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->ColorDestinationBlend),
                    srcAlphaBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->AlphaSourceBlend),
                    srcColorBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->ColorSourceBlend),
                    colorWriteMask      = VulkanConvertExtensions.ConvertColorWriteChannels(renderTargetBlendState->ColorWriteChannels),
                };

                if (description.IndependentBlendEnable)
                {
                    renderTargetBlendState++;
                }
            }

            var viewportState = new VkPipelineViewportStateCreateInfo
            {
                sType         = VkStructureType.PipelineViewportStateCreateInfo,
                scissorCount  = 1,
                viewportCount = 1,
            };

            fixed(void *dynamicStatesPointer   = dynamicStates.Length == 0?null : dynamicStates,
                  inputAttributesPointer       = inputAttributes.Length == 0?null : inputAttributes,
                  inputBindingsPointer         = inputBindings.Length == 0?null : inputBindings,
                  colorBlendAttachmentsPointer = colorBlendAttachments.Length == 0?null : colorBlendAttachments,
                  stagesPointer = stages.Length == 0?null : stages)
            {
                var vertexInputState = new VkPipelineVertexInputStateCreateInfo
                {
                    sType = VkStructureType.PipelineVertexInputStateCreateInfo,
                    vertexAttributeDescriptionCount = (uint)inputAttributeCount,
                    pVertexAttributeDescriptions    = (Vortice.Vulkan.VkVertexInputAttributeDescription *)inputAttributesPointer,
                    vertexBindingDescriptionCount   = (uint)inputBindingCount,
                    pVertexBindingDescriptions      = (Vortice.Vulkan.VkVertexInputBindingDescription *)inputBindingsPointer,
                };

                var colorBlendState = new VkPipelineColorBlendStateCreateInfo
                {
                    sType           = VkStructureType.PipelineColorBlendStateCreateInfo,
                    attachmentCount = (uint)renderTargetCount,
                    pAttachments    = (Vortice.Vulkan.VkPipelineColorBlendAttachmentState *)colorBlendAttachmentsPointer,
                };

                var dynamicState = new VkPipelineDynamicStateCreateInfo
                {
                    sType             = VkStructureType.PipelineDynamicStateCreateInfo,
                    dynamicStateCount = (uint)dynamicStates.Length,
                    pDynamicStates    = (Vortice.Vulkan.VkDynamicState *)dynamicStatesPointer,
                };

                var createInfo = new VkGraphicsPipelineCreateInfo
                {
                    sType               = VkStructureType.GraphicsPipelineCreateInfo,
                    layout              = NativeLayout,
                    stageCount          = (uint)stages.Length,
                    pVertexInputState   = &vertexInputState,
                    pInputAssemblyState = &inputAssemblyState,
                    pRasterizationState = &rasterizationState,
                    pMultisampleState   = &multisampleState,
                    pDepthStencilState  = &depthStencilState,
                    pColorBlendState    = &colorBlendState,
                    pDynamicState       = &dynamicState,
                    pStages             = (Vortice.Vulkan.VkPipelineShaderStageCreateInfo *)stagesPointer,
                    pViewportState      = &viewportState,
                    renderPass          = NativeRenderPass,
                    subpass             = 0,
                };

                using (GraphicsDevice.QueueLock.ReadLock())
                {
                    vkCreateRenderPass(GraphicsDevice.NativeDevice, &renderPassCreateInfo, null, out NativeRenderPass);
                    vkCreatePipelineLayout(GraphicsDevice.NativeDevice, &pipelineLayoutCreateInfo, null, out NativeLayout);

                    createInfo.layout     = NativeLayout;
                    createInfo.renderPass = NativeRenderPass;

                    try {
                        fixed(VkPipeline *nativePipelinePtr = &NativePipeline)
                        vkCreateGraphicsPipelines(GraphicsDevice.NativeDevice, VkPipelineCache.Null, 1, &createInfo, null, nativePipelinePtr);
                    } catch (Exception e) {
                        errorDuringCreate = true;
                        NativePipeline    = VkPipeline.Null;
                    }
                }
            }

            // Cleanup shader modules
            for (int i = 0; i < stages.Length; i++)
            {
                vkDestroyShaderModule(GraphicsDevice.NativeDevice, stages[i].module, null);
            }
        }
Ejemplo n.º 2
0
        void CreateRenderPass(RenderPassCreateInfo mInfo)
        {
            unsafe
            {
                var info = new VkRenderPassCreateInfo();
                info.sType = VkStructureType.RenderPassCreateInfo;

                //for CreateInfo
                int attachmentCount = 0;
                int subpassCount    = 0;
                int dependencyCount = 0;

                //for CreateInfo.subpasses
                int totalInputAttachments        = 0;
                int totalColorAttachments        = 0;
                int totalResolveAttachments      = 0;
                int totalDepthStencilAttachments = 0;
                int totalPreserveAttachments     = 0;

                if (mInfo.attachments != null)
                {
                    attachmentCount = mInfo.attachments.Count;
                }
                if (mInfo.subpasses != null)
                {
                    subpassCount = mInfo.subpasses.Count;
                }
                if (mInfo.dependencies != null)
                {
                    dependencyCount = mInfo.dependencies.Count;
                }

                for (int i = 0; i < subpassCount; i++)
                {
                    var subpass = mInfo.subpasses[i];
                    if (subpass.inputAttachments != null)
                    {
                        totalInputAttachments += subpass.inputAttachments.Count;
                    }
                    if (subpass.colorAttachments != null)
                    {
                        totalColorAttachments += subpass.colorAttachments.Count;
                    }
                    if (subpass.resolveAttachments != null)
                    {
                        totalResolveAttachments += subpass.resolveAttachments.Count;
                    }
                    if (subpass.depthStencilAttachment != null)
                    {
                        totalDepthStencilAttachments += 1;
                    }
                    if (subpass.preserveAttachments != null)
                    {
                        totalPreserveAttachments += subpass.preserveAttachments.Count;
                    }
                }

                //for CreateInfo
                var attachments  = stackalloc VkAttachmentDescription[attachmentCount];
                var subpasses    = stackalloc VkSubpassDescription[subpassCount];
                var dependencies = stackalloc VkSubpassDependency[dependencyCount];

                //for CreateInfo.subpasses
                var inputAttachments    = stackalloc VkAttachmentReference[totalInputAttachments];
                var colorAttachments    = stackalloc VkAttachmentReference[totalColorAttachments];
                var resolveAttachments  = stackalloc VkAttachmentReference[totalResolveAttachments];
                var depthAttachments    = stackalloc VkAttachmentReference[totalDepthStencilAttachments];
                var preserveAttachments = stackalloc uint[totalPreserveAttachments];

                int inputIndex    = 0;
                int colorIndex    = 0;
                int resolveIndex  = 0;
                int depthIndex    = 0;
                int preserveIndex = 0;

                //marshal CreateInfo.attachments
                for (int i = 0; i < attachmentCount; i++)
                {
                    attachments[i].flags          = mInfo.attachments[i].flags;
                    attachments[i].format         = mInfo.attachments[i].format;
                    attachments[i].samples        = mInfo.attachments[i].samples;
                    attachments[i].loadOp         = mInfo.attachments[i].loadOp;
                    attachments[i].storeOp        = mInfo.attachments[i].storeOp;
                    attachments[i].stencilLoadOp  = mInfo.attachments[i].stencilLoadOp;
                    attachments[i].stencilStoreOp = mInfo.attachments[i].stencilStoreOp;
                    attachments[i].initialLayout  = mInfo.attachments[i].initialLayout;
                    attachments[i].finalLayout    = mInfo.attachments[i].finalLayout;
                }

                //marshal CreateInfo.subpasses
                for (int i = 0; i < subpassCount; i++)
                {
                    var subpass = mInfo.subpasses[i];
                    if (subpass.inputAttachments != null)
                    {
                        for (int j = 0; j < subpass.inputAttachments.Count; j++)
                        {
                            inputAttachments[j + inputIndex] = new VkAttachmentReference {
                                attachment = subpass.inputAttachments[j].attachment,
                                layout     = subpass.inputAttachments[j].layout
                            };
                        }

                        subpasses[i].inputAttachmentCount = (uint)subpass.inputAttachments.Count;
                        subpasses[i].pInputAttachments    = (IntPtr)(&inputAttachments[inputIndex]);
                        inputIndex += subpass.inputAttachments.Count;
                    }
                    if (subpass.colorAttachments != null)
                    {
                        for (int j = 0; j < subpass.colorAttachments.Count; j++)
                        {
                            colorAttachments[j + colorIndex] = new VkAttachmentReference {
                                attachment = subpass.colorAttachments[j].attachment,
                                layout     = subpass.colorAttachments[j].layout
                            };
                        }

                        subpasses[i].colorAttachmentCount = (uint)subpass.colorAttachments.Count;
                        subpasses[i].pColorAttachments    = (IntPtr)(&colorAttachments[colorIndex]);
                        colorIndex += subpass.colorAttachments.Count;
                    }
                    if (subpass.resolveAttachments != null)
                    {
                        for (int j = 0; j < subpass.resolveAttachments.Count; j++)
                        {
                            resolveAttachments[j + resolveIndex] = new VkAttachmentReference {
                                attachment = subpass.resolveAttachments[j].attachment,
                                layout     = subpass.resolveAttachments[j].layout
                            };
                        }

                        subpasses[i].pResolveAttachments = (IntPtr)(&resolveAttachments[resolveIndex]);
                        resolveIndex += subpass.resolveAttachments.Count;
                    }
                    if (subpass.depthStencilAttachment != null)
                    {
                        depthAttachments[depthIndex] = new VkAttachmentReference {
                            attachment = subpass.depthStencilAttachment.attachment,
                            layout     = subpass.depthStencilAttachment.layout
                        };

                        subpasses[i].pDepthStencilAttachment = (IntPtr)(&depthAttachments[depthIndex]);
                        depthIndex += 1;
                    }
                    if (subpass.preserveAttachments != null)
                    {
                        for (int j = 0; j < subpass.preserveAttachments.Count; j++)
                        {
                            preserveAttachments[j + preserveIndex] = subpass.preserveAttachments[j];
                        }

                        subpasses[i].preserveAttachmentCount = (uint)subpass.preserveAttachments.Count;
                        subpasses[i].pPreserveAttachments    = (IntPtr)(&preserveAttachments[preserveIndex]);
                        preserveIndex += subpass.preserveAttachments.Count;
                    }

                    subpasses[i].pipelineBindPoint = subpass.pipelineBindPoint;
                }

                //marshal CreateInfo.dependencies
                for (int i = 0; i < dependencyCount; i++)
                {
                    dependencies[i].srcSubpass      = mInfo.dependencies[i].srcSubpass;
                    dependencies[i].dstSubpass      = mInfo.dependencies[i].dstSubpass;
                    dependencies[i].srcStageMask    = mInfo.dependencies[i].srcStageMask;
                    dependencies[i].dstStageMask    = mInfo.dependencies[i].dstStageMask;
                    dependencies[i].srcAccessMask   = mInfo.dependencies[i].srcAccessMask;
                    dependencies[i].dependencyFlags = mInfo.dependencies[i].dependencyFlags;
                }

                //marshal CreateInfo
                info.attachmentCount = (uint)attachmentCount;
                info.pAttachments    = (IntPtr)attachments;
                info.subpassCount    = (uint)subpassCount;
                info.pSubpasses      = (IntPtr)subpasses;
                info.dependencyCount = (uint)dependencyCount;
                info.pDependencies   = (IntPtr)dependencies;

                var result = Device.Commands.createRenderPass(Device.Native, ref info, Device.Instance.AllocationCallbacks, out renderPass);
                if (result != VkResult.Success)
                {
                    throw new RenderPassException(string.Format("Error creating render pass: {0}"));
                }

                GetGranularity();
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Builds a new render pass
        /// </summary>
        /// <returns>the new render pass</returns>
        public RenderPassWithIdentifiers <TAttachment, TPass> Build()
        {
            Dictionary <TPass, int> passInFactory = new Dictionary <TPass, int>();

            foreach (var pass in _subpassBuilders)
            {
                passInFactory.Add(pass.Key, 0);
            }
            foreach (var dep in _dependencyBuilders)
            {
                if (!dep.DstExternal && !dep.SrcExternal)
                {
                    passInFactory[dep.DstPass]++;
                }
            }
            var          passComparer = EqualityComparer <TPass> .Default;
            List <TPass> passOrder    = new List <TPass>();

            while (passOrder.Count < _subpassBuilders.Count)
            {
                var insert = passInFactory.Where(x => x.Value == 0).Select(x => x.Key).ToList();
                if (insert.Count == 0)
                {
                    throw new Exception($"Circular dependency detected in {string.Join(", ", passInFactory)}.");
                }
                passOrder.AddRange(insert);
                foreach (var k in insert)
                {
                    passInFactory.Remove(k);
                    foreach (var dep in _dependencyBuilders.Where(x =>
                                                                  !x.SrcExternal && !x.DstExternal && passComparer.Equals(x.SrcPass, k)))
                    {
                        passInFactory[dep.DstPass]--;
                    }
                }
            }
            var attachmentToId = _attachmentOrder.Select((x, i) => new KeyValuePair <TAttachment, uint>(x, (uint)i))
                                 .ToDictionary(a => a.Key, b => b.Value);

            var passToId = passOrder.Select((x, i) => new KeyValuePair <TPass, uint>(x, (uint)i))
                           .ToDictionary(a => a.Key, b => b.Value);

            var pins           = new List <GCHandle>();
            var attachmentDesc = new VkAttachmentDescription[_attachmentOrder.Count];
            var passDesc       = new VkSubpassDescription[passOrder.Count];
            var dependencyDesc = new VkSubpassDependency[_dependencyBuilders.Count];

            try
            {
                foreach (var attachment in attachmentToId)
                {
                    attachmentDesc[attachment.Value] = _attachmentDescriptions[attachment.Key];
                }
                foreach (var pass in passToId)
                {
                    passDesc[pass.Value] = _subpassBuilders[pass.Key].Build(pins, attachmentToId);
                }
                var i = 0;
                foreach (var dep in _dependencyBuilders)
                {
                    dependencyDesc[i++] = dep.Build(passToId);
                }
                Debug.Assert(i == dependencyDesc.Length);
                Array.Sort(dependencyDesc,
                           (a, b) => a.SrcSubpass != Vulkan.SubpassExternal
                        ? a.SrcSubpass.CompareTo(b.SrcSubpass)
                        : a.DstSubpass.CompareTo(b.DstSubpass));

                unsafe
                {
                    fixed(VkAttachmentDescription *attachPtr = attachmentDesc)
                    fixed(VkSubpassDescription * passPtr = passDesc)
                    fixed(VkSubpassDependency * depPtr   = dependencyDesc)
                    {
                        var info = new VkRenderPassCreateInfo()
                        {
                            SType           = VkStructureType.RenderPassCreateInfo,
                            Flags           = 0,
                            PNext           = IntPtr.Zero,
                            AttachmentCount = (uint)attachmentDesc.Length,
                            PAttachments    = attachPtr,
                            SubpassCount    = (uint)passDesc.Length,
                            PSubpasses      = passPtr,
                            DependencyCount = (uint)dependencyDesc.Length,
                            PDependencies   = depPtr,
                        };

                        return(new RenderPassWithIdentifiers <TAttachment, TPass>(_dev, info, _attachmentOrder.ToArray(),
                                                                                  passOrder.ToArray()));
                    }
                }
            }
            finally
            {
                foreach (var pin in pins)
                {
                    pin.Free();
                }
            }
        }
Ejemplo n.º 4
0
        public VkFramebuffer(VkGraphicsDevice gd, ref FramebufferDescription description, bool isPresented)
            : base(description.DepthTarget, description.ColorTargets)
        {
            _gd = gd;

            VkRenderPassCreateInfo renderPassCI = VkRenderPassCreateInfo.New();

            StackList <VkAttachmentDescription> attachments = new StackList <VkAttachmentDescription>();

            uint colorAttachmentCount = (uint)ColorTargets.Count;
            StackList <VkAttachmentReference> colorAttachmentRefs = new StackList <VkAttachmentReference>();

            for (int i = 0; i < colorAttachmentCount; i++)
            {
                VkTexture vkColorTex = Util.AssertSubtype <Texture, VkTexture>(ColorTargets[i].Target);
                VkAttachmentDescription colorAttachmentDesc = new VkAttachmentDescription();
                colorAttachmentDesc.format         = vkColorTex.VkFormat;
                colorAttachmentDesc.samples        = vkColorTex.VkSampleCount;
                colorAttachmentDesc.loadOp         = VkAttachmentLoadOp.DontCare;
                colorAttachmentDesc.storeOp        = VkAttachmentStoreOp.Store;
                colorAttachmentDesc.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                colorAttachmentDesc.stencilStoreOp = VkAttachmentStoreOp.DontCare;
                colorAttachmentDesc.initialLayout  = VkImageLayout.Undefined;
                colorAttachmentDesc.finalLayout    = VkImageLayout.ColorAttachmentOptimal;
                attachments.Add(colorAttachmentDesc);

                VkAttachmentReference colorAttachmentRef = new VkAttachmentReference();
                colorAttachmentRef.attachment = (uint)i;
                colorAttachmentRef.layout     = VkImageLayout.ColorAttachmentOptimal;
                colorAttachmentRefs.Add(colorAttachmentRef);
            }

            VkAttachmentDescription depthAttachmentDesc = new VkAttachmentDescription();
            VkAttachmentReference   depthAttachmentRef  = new VkAttachmentReference();

            if (DepthTarget != null)
            {
                VkTexture vkDepthTex = Util.AssertSubtype <Texture, VkTexture>(DepthTarget.Value.Target);
                bool      hasStencil = FormatHelpers.IsStencilFormat(vkDepthTex.Format);
                depthAttachmentDesc.format         = vkDepthTex.VkFormat;
                depthAttachmentDesc.samples        = vkDepthTex.VkSampleCount;
                depthAttachmentDesc.loadOp         = VkAttachmentLoadOp.DontCare;
                depthAttachmentDesc.storeOp        = VkAttachmentStoreOp.Store;
                depthAttachmentDesc.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                depthAttachmentDesc.stencilStoreOp = hasStencil ? VkAttachmentStoreOp.Store : VkAttachmentStoreOp.DontCare;
                depthAttachmentDesc.initialLayout  = VkImageLayout.Undefined;
                depthAttachmentDesc.finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal;

                depthAttachmentRef.attachment = (uint)description.ColorTargets.Length;
                depthAttachmentRef.layout     = VkImageLayout.DepthStencilAttachmentOptimal;
            }

            VkSubpassDescription subpass = new VkSubpassDescription();

            subpass.pipelineBindPoint = VkPipelineBindPoint.Graphics;
            if (ColorTargets.Count > 0)
            {
                subpass.colorAttachmentCount = colorAttachmentCount;
                subpass.pColorAttachments    = (VkAttachmentReference *)colorAttachmentRefs.Data;
            }

            if (DepthTarget != null)
            {
                subpass.pDepthStencilAttachment = &depthAttachmentRef;
                attachments.Add(depthAttachmentDesc);
            }

            VkSubpassDependency subpassDependency = new VkSubpassDependency();

            subpassDependency.srcSubpass    = SubpassExternal;
            subpassDependency.srcStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite;
            if (DepthTarget != null)
            {
                subpassDependency.dstAccessMask |= VkAccessFlags.DepthStencilAttachmentRead | VkAccessFlags.DepthStencilAttachmentWrite;
            }

            renderPassCI.attachmentCount = attachments.Count;
            renderPassCI.pAttachments    = (VkAttachmentDescription *)attachments.Data;
            renderPassCI.subpassCount    = 1;
            renderPassCI.pSubpasses      = &subpass;
            renderPassCI.dependencyCount = 1;
            renderPassCI.pDependencies   = &subpassDependency;

            VkResult creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPassNoClear);

            CheckResult(creationResult);

            for (int i = 0; i < colorAttachmentCount; i++)
            {
                attachments[i].loadOp        = VkAttachmentLoadOp.Load;
                attachments[i].initialLayout = VkImageLayout.ColorAttachmentOptimal;
            }
            if (DepthTarget != null)
            {
                attachments[attachments.Count - 1].loadOp        = VkAttachmentLoadOp.Load;
                attachments[attachments.Count - 1].initialLayout = VkImageLayout.DepthStencilAttachmentOptimal;
                bool hasStencil = FormatHelpers.IsStencilFormat(DepthTarget.Value.Target.Format);
                if (hasStencil)
                {
                    attachments[attachments.Count - 1].stencilLoadOp = VkAttachmentLoadOp.Load;
                }
            }
            creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPassNoClearLoad);
            CheckResult(creationResult);


            // Load version

            if (DepthTarget != null)
            {
                attachments[attachments.Count - 1].loadOp        = VkAttachmentLoadOp.Clear;
                attachments[attachments.Count - 1].initialLayout = VkImageLayout.Undefined;
                bool hasStencil = FormatHelpers.IsStencilFormat(DepthTarget.Value.Target.Format);
                if (hasStencil)
                {
                    attachments[attachments.Count - 1].stencilLoadOp = VkAttachmentLoadOp.Clear;
                }
            }

            for (int i = 0; i < colorAttachmentCount; i++)
            {
                attachments[i].loadOp        = VkAttachmentLoadOp.Clear;
                attachments[i].initialLayout = VkImageLayout.Undefined;
            }

            creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPassClear);
            CheckResult(creationResult);

            VkFramebufferCreateInfo fbCI = VkFramebufferCreateInfo.New();
            uint fbAttachmentsCount      = (uint)description.ColorTargets.Length;

            if (description.DepthTarget != null)
            {
                fbAttachmentsCount += 1;
            }

            VkImageView *fbAttachments = stackalloc VkImageView[(int)fbAttachmentsCount];

            for (int i = 0; i < colorAttachmentCount; i++)
            {
                VkTexture             vkColorTarget = Util.AssertSubtype <Texture, VkTexture>(description.ColorTargets[i].Target);
                VkImageViewCreateInfo imageViewCI   = VkImageViewCreateInfo.New();
                imageViewCI.image            = vkColorTarget.OptimalDeviceImage;
                imageViewCI.format           = vkColorTarget.VkFormat;
                imageViewCI.viewType         = VkImageViewType.Image2D;
                imageViewCI.subresourceRange = new VkImageSubresourceRange(
                    VkImageAspectFlags.Color,
                    description.ColorTargets[i].MipLevel,
                    1,
                    description.ColorTargets[i].ArrayLayer,
                    1);
                VkImageView *dest   = (fbAttachments + i);
                VkResult     result = vkCreateImageView(_gd.Device, ref imageViewCI, null, dest);
                CheckResult(result);
                _attachmentViews.Add(*dest);
            }

            // Depth
            if (description.DepthTarget != null)
            {
                VkTexture             vkDepthTarget = Util.AssertSubtype <Texture, VkTexture>(description.DepthTarget.Value.Target);
                bool                  hasStencil    = FormatHelpers.IsStencilFormat(vkDepthTarget.Format);
                VkImageViewCreateInfo depthViewCI   = VkImageViewCreateInfo.New();
                depthViewCI.image            = vkDepthTarget.OptimalDeviceImage;
                depthViewCI.format           = vkDepthTarget.VkFormat;
                depthViewCI.viewType         = description.DepthTarget.Value.Target.ArrayLayers == 1 ? VkImageViewType.Image2D : VkImageViewType.Image2DArray;
                depthViewCI.subresourceRange = new VkImageSubresourceRange(
                    hasStencil ? VkImageAspectFlags.Depth | VkImageAspectFlags.Stencil : VkImageAspectFlags.Depth,
                    description.DepthTarget.Value.MipLevel,
                    1,
                    description.DepthTarget.Value.ArrayLayer,
                    1);
                VkImageView *dest   = (fbAttachments + (fbAttachmentsCount - 1));
                VkResult     result = vkCreateImageView(_gd.Device, ref depthViewCI, null, dest);
                CheckResult(result);
                _attachmentViews.Add(*dest);
            }

            Texture dimTex;
            uint    mipLevel;

            if (ColorTargets.Count > 0)
            {
                dimTex   = ColorTargets[0].Target;
                mipLevel = ColorTargets[0].MipLevel;
            }
            else
            {
                Debug.Assert(DepthTarget != null);
                dimTex   = DepthTarget.Value.Target;
                mipLevel = DepthTarget.Value.MipLevel;
            }

            Util.GetMipDimensions(
                dimTex,
                mipLevel,
                out uint mipWidth,
                out uint mipHeight,
                out _);

            fbCI.width  = mipWidth;
            fbCI.height = mipHeight;

            fbCI.attachmentCount = fbAttachmentsCount;
            fbCI.pAttachments    = fbAttachments;
            fbCI.layers          = 1;
            fbCI.renderPass      = _renderPassNoClear;

            creationResult = vkCreateFramebuffer(_gd.Device, ref fbCI, null, out _deviceFramebuffer);
            CheckResult(creationResult);

            if (DepthTarget != null)
            {
                AttachmentCount += 1;
            }
            AttachmentCount += (uint)ColorTargets.Count;
        }
        private VkRenderPass CreateRenderPass()
        {
            VkAttachmentDescription *attachments = stackalloc VkAttachmentDescription[2]
            {
                // Color attachment.
                new VkAttachmentDescription
                {
                    format         = SwapchainFormat,
                    samples        = VkSampleCountFlags.Count1,
                    loadOp         = VkAttachmentLoadOp.Clear,
                    storeOp        = VkAttachmentStoreOp.Store,
                    stencilLoadOp  = VkAttachmentLoadOp.DontCare,
                    stencilStoreOp = VkAttachmentStoreOp.DontCare,
                    initialLayout  = VkImageLayout.Undefined,
                    finalLayout    = VkImageLayout.PresentSrcKHR
                },
                // Depth attachment.
                new VkAttachmentDescription
                {
                    format         = _depthStencilBuffer.Format,
                    samples        = VkSampleCountFlags.Count1,
                    loadOp         = VkAttachmentLoadOp.Clear,
                    storeOp        = VkAttachmentStoreOp.DontCare,
                    stencilLoadOp  = VkAttachmentLoadOp.DontCare,
                    stencilStoreOp = VkAttachmentStoreOp.DontCare,
                    initialLayout  = VkImageLayout.Undefined,
                    finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal
                }
            };


            VkAttachmentReference colorAttachment = new VkAttachmentReference
            {
                attachment = 0,
                layout     = VkImageLayout.ColorAttachmentOptimal
            };
            VkAttachmentReference depthStencilAttachment = new VkAttachmentReference
            {
                attachment = 1,
                layout     = VkImageLayout.DepthStencilAttachmentOptimal
            };

            var subpass = new VkSubpassDescription
            {
                colorAttachmentCount    = 1,
                pColorAttachments       = &colorAttachment,
                pDepthStencilAttachment = &depthStencilAttachment
            };

            VkSubpassDependency *dependencies = stackalloc VkSubpassDependency[2]
            {
                new VkSubpassDependency
                {
                    srcSubpass      = uint.MaxValue, // SubpassExternal ?
                    dstSubpass      = 0,
                    srcStageMask    = VkPipelineStageFlags.BottomOfPipe,
                    dstStageMask    = VkPipelineStageFlags.ColorAttachmentOutput,
                    srcAccessMask   = VkAccessFlags.MemoryRead,
                    dstAccessMask   = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite,
                    dependencyFlags = VkDependencyFlags.ByRegion
                },
                new VkSubpassDependency
                {
                    srcSubpass      = 0,
                    dstSubpass      = uint.MaxValue, // SubpassExternal ?
                    srcStageMask    = VkPipelineStageFlags.ColorAttachmentOutput,
                    dstStageMask    = VkPipelineStageFlags.BottomOfPipe,
                    srcAccessMask   = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite,
                    dstAccessMask   = VkAccessFlags.MemoryRead,
                    dependencyFlags = VkDependencyFlags.ByRegion
                }
            };

            var createInfo = new VkRenderPassCreateInfo
            {
                sType           = VkStructureType.RenderPassCreateInfo,
                pNext           = null,
                subpassCount    = 1,
                pSubpasses      = &subpass,
                attachmentCount = 2,
                pAttachments    = attachments,
                dependencyCount = 2,
                pDependencies   = dependencies
            };


            VkRenderPass renderPass;

            vkCreateRenderPass(Context.Device, &createInfo, null, out renderPass).CheckResult();
            return(renderPass);
        }
Ejemplo n.º 6
0
 public static extern VkResult CreateRenderPass(
     VkDevice device,
     ref VkRenderPassCreateInfo pCreateInfo,
     IntPtr pAllocator,
     out VkRenderPass pRenderPass
     );
Ejemplo n.º 7
0
        private unsafe void CreateRenderPass(PipelineStateDescription pipelineStateDescription)
        {
            bool hasDepthStencilAttachment = pipelineStateDescription.Output.DepthStencilFormat != PixelFormat.None;

            var renderTargetCount = pipelineStateDescription.Output.RenderTargetCount;

            var attachmentCount = renderTargetCount;

            if (hasDepthStencilAttachment)
            {
                attachmentCount++;
            }

            var attachments = new VkAttachmentDescription[attachmentCount];
            var colorAttachmentReferences = new VkAttachmentReference[renderTargetCount];

            fixed(PixelFormat *renderTargetFormat = &pipelineStateDescription.Output.RenderTargetFormat0)
            fixed(BlendStateRenderTargetDescription * blendDescription = &pipelineStateDescription.BlendState.RenderTarget0)
            {
                for (int i = 0; i < renderTargetCount; i++)
                {
                    var currentBlendDesc = pipelineStateDescription.BlendState.IndependentBlendEnable ? (blendDescription + i) : blendDescription;

                    attachments[i] = new VkAttachmentDescription
                    {
                        format         = VulkanConvertExtensions.ConvertPixelFormat(*(renderTargetFormat + i)),
                        samples        = VkSampleCountFlags.Count1,
                        loadOp         = currentBlendDesc->BlendEnable ? VkAttachmentLoadOp.Load : VkAttachmentLoadOp.DontCare, // TODO VULKAN: Only if any destination blend?
                        storeOp        = VkAttachmentStoreOp.Store,
                        stencilLoadOp  = VkAttachmentLoadOp.DontCare,
                        stencilStoreOp = VkAttachmentStoreOp.DontCare,
                        initialLayout  = VkImageLayout.ColorAttachmentOptimal,
                        finalLayout    = VkImageLayout.ColorAttachmentOptimal,
                    };

                    colorAttachmentReferences[i] = new VkAttachmentReference
                    {
                        attachment = (uint)i,
                        layout     = VkImageLayout.ColorAttachmentOptimal,
                    };
                }
            }

            if (hasDepthStencilAttachment)
            {
                attachments[attachmentCount - 1] = new VkAttachmentDescription
                {
                    format         = Texture.GetFallbackDepthStencilFormat(GraphicsDevice, VulkanConvertExtensions.ConvertPixelFormat(pipelineStateDescription.Output.DepthStencilFormat)),
                    samples        = VkSampleCountFlags.Count1,
                    loadOp         = VkAttachmentLoadOp.Load,     // TODO VULKAN: Only if depth read enabled?
                    storeOp        = VkAttachmentStoreOp.Store,   // TODO VULKAN: Only if depth write enabled?
                    stencilLoadOp  = VkAttachmentLoadOp.DontCare, // TODO VULKAN: Handle stencil
                    stencilStoreOp = VkAttachmentStoreOp.DontCare,
                    initialLayout  = VkImageLayout.DepthStencilAttachmentOptimal,
                    finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal,
                };
            }

            var depthAttachmentReference = new VkAttachmentReference
            {
                attachment = (uint)attachments.Length - 1,
                layout     = VkImageLayout.DepthStencilAttachmentOptimal,
            };

            var subpass = new VkSubpassDescription
            {
                pipelineBindPoint       = VkPipelineBindPoint.Graphics,
                colorAttachmentCount    = (uint)renderTargetCount,
                pColorAttachments       = colorAttachmentReferences.Length > 0 ? (VkAttachmentReference *)Core.Interop.Fixed(colorAttachmentReferences) : null,
                pDepthStencilAttachment = hasDepthStencilAttachment ? &depthAttachmentReference : null,
            };

            var renderPassCreateInfo = new VkRenderPassCreateInfo
            {
                sType           = VkStructureType.RenderPassCreateInfo,
                attachmentCount = (uint)attachmentCount,
                pAttachments    = attachments.Length > 0 ? (VkAttachmentDescription *)Core.Interop.Fixed(attachments) : null,
                subpassCount    = 1,
                pSubpasses      = &subpass,
            };

            vkCreateRenderPass(GraphicsDevice.NativeDevice, &renderPassCreateInfo, null, out NativeRenderPass);
        }
Ejemplo n.º 8
0
        internal void CreateRenderPass()
        {
            VkFormat color_format = SwapChain.color_format;
            VkFormat depth_format = SwapChain.DepthStencil.Format;


            // Descriptors for the attachments used by this renderpass
            VkAttachmentDescription *attachments = stackalloc VkAttachmentDescription[2]
            {
                // Color attachment
                new VkAttachmentDescription
                {
                    format         = color_format,                                   // Use the color format selected by the swapchain
                    samples        = VkSampleCountFlags.Count1,                      // We don't use multi sampling in this example
                    loadOp         = VkAttachmentLoadOp.Clear,                       // Clear this attachment at the start of the render pass
                    storeOp        = VkAttachmentStoreOp.Store,                      // Keep it's contents after the render pass is finished (for displaying it)
                    stencilLoadOp  = VkAttachmentLoadOp.DontCare,                    // We don't use stencil, so don't care for load
                    stencilStoreOp = VkAttachmentStoreOp.DontCare,                   // Same for store
                    initialLayout  = VkImageLayout.Undefined,                        // Layout at render pass start. Initial doesn't matter, so we use undefined
                    finalLayout    = VkImageLayout.PresentSrcKHR                     // Layout to which the attachment is transitioned when the render pass is finished
                },



                // Use the color format selected by the swapchain
                // As we want to present the color buffer to the swapchain, we transition to PRESENT_KHR
                // Depth attachment
                // A proper depth format is selected in the example base

                new VkAttachmentDescription
                {
                    format         = depth_format,                                   // A proper depth format is selected in the example base
                    samples        = VkSampleCountFlags.Count1,
                    loadOp         = VkAttachmentLoadOp.Clear,                       // Clear depth at start of first subpass
                    storeOp        = VkAttachmentStoreOp.DontCare,                   // We don't need depth after render pass has finished (DONT_CARE may result in better performance)
                    stencilLoadOp  = VkAttachmentLoadOp.DontCare,                    // No stencil
                    stencilStoreOp = VkAttachmentStoreOp.DontCare,                   // No Stencil
                    initialLayout  = VkImageLayout.Undefined,                        // Layout at render pass start. Initial doesn't matter, so we use undefined
                    finalLayout    = VkImageLayout.ColorAttachmentOptimal            // Transition to depth/stencil attachment
                },
            };


            // Setup attachment references
            VkAttachmentReference *colorReferences = stackalloc VkAttachmentReference[1]
            {
                new VkAttachmentReference                                               // Attachment layout used as color during the subpass
                {
                    attachment = 0,                                                     // Attachment 0 is color
                    layout     = VkImageLayout.ColorAttachmentOptimal
                }
            };


            VkAttachmentReference depthReference = new VkAttachmentReference
            {
                attachment = 1,                                                             // Attachment 1 is color
                layout     = VkImageLayout.DepthStencilAttachmentOptimal                    // Attachment used as depth/stemcil used during the subpass
            };


            // Setup a single subpass reference
            VkSubpassDescription *subpass_description = stackalloc VkSubpassDescription[1]
            {
                new VkSubpassDescription
                {
                    pipelineBindPoint       = VkPipelineBindPoint.Graphics,
                    colorAttachmentCount    = 1,                                                // Subpass uses one color attachment
                    pColorAttachments       = colorReferences,                                  // Reference to the color attachment in slot 0
                    pDepthStencilAttachment = &depthReference,                                  // Reference to the depth attachment in slot 1
                    inputAttachmentCount    = 0,                                                // Input attachments can be used to sample from contents of a previous subpass
                    pInputAttachments       = null,                                             // (Input attachments not used by this example)
                    preserveAttachmentCount = 0,                                                // Preserved attachments can be used to loop (and preserve) attachments through subpasses
                    pPreserveAttachments    = null,                                             // (Preserve attachments not used by this example)
                    pResolveAttachments     = null                                              // Resolve attachments are resolved at the end of a sub pass and can be used for e.g. multi sampling
                },
            };



            // Setup subpass dependencies
            // These will add the implicit ttachment layout transitionss specified by the attachment descriptions
            // The actual usage layout is preserved through the layout specified in the attachment reference
            // Each subpass dependency will introduce a memory and execution dependency between the source and dest subpass described by
            // srcStageMask, dstStageMask, srcAccessMask, dstAccessMask (and dependencyFlags is set)
            // Note: VK_SUBPASS_EXTERNAL is a special constant that refers to all commands executed outside of the actual renderpass)
            VkSubpassDependency *dependencies = stackalloc VkSubpassDependency[2]
            {
                // First dependency at the start of the renderpass
                // Does the transition from final to initial layout
                new VkSubpassDependency
                {
                    srcSubpass      = SubpassExternal,                              // Producer of the dependency
                    dstSubpass      = 0,                                            // Consumer is our single subpass that will wait for the execution depdendency
                    srcStageMask    = VkPipelineStageFlags.BottomOfPipe,
                    dstStageMask    = VkPipelineStageFlags.ColorAttachmentOutput,
                    srcAccessMask   = VkAccessFlags.MemoryRead,
                    dstAccessMask   = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite,
                    dependencyFlags = VkDependencyFlags.ByRegion
                },

                // Second dependency at the end the renderpass
                // Does the transition from the initial to the final layout
                new VkSubpassDependency
                {
                    srcSubpass      = 0,                                            // Producer of the dependency is our single subpass
                    dstSubpass      = SubpassExternal,                              // Consumer are all commands outside of the renderpass
                    srcStageMask    = VkPipelineStageFlags.ColorAttachmentOutput,
                    dstStageMask    = VkPipelineStageFlags.BottomOfPipe,
                    srcAccessMask   = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite,
                    dstAccessMask   = VkAccessFlags.MemoryRead,
                    dependencyFlags = VkDependencyFlags.ByRegion
                }
            };



            // Create the actual renderpass
            VkRenderPassCreateInfo render_pass_info = new VkRenderPassCreateInfo()
            {
                sType           = VkStructureType.RenderPassCreateInfo,
                attachmentCount = 2,                                             // Number of attachments used by this render pass
                pAttachments    = attachments,                                   // Descriptions of the attachments used by the render pass
                subpassCount    = 1,                                             // We only use one subpass in this example
                pSubpasses      = subpass_description,                           // Description of that subpass
                dependencyCount = 2,                                             // Number of subpass dependencies
                pDependencies   = dependencies,
            };

            vkCreateRenderPass(NativeDevice.handle, &render_pass_info, null, out renderPass).CheckResult();
        }
Ejemplo n.º 9
0
 public static VkRenderPass CreateRenderPass(ref VkRenderPassCreateInfo createInfo)
 {
     VulkanUtil.CheckResult(vkCreateRenderPass(device, Utilities.AsPtr(ref createInfo), null, out VkRenderPass pRenderPass));
     return(pRenderPass);
 }
Ejemplo n.º 10
0
        // Setup the offscreen framebuffer for rendering the blurred scene
        // The color attachment of this framebuffer will then be used to sample frame in the fragment shader of the final pass
        void prepareOffscreen()
        {
            offscreenPass.width  = FB_DIM;
            offscreenPass.height = FB_DIM;

            // Find a suitable depth format
            VkFormat fbDepthFormat;
            VkBool32 validDepthFormat = Tools.getSupportedDepthFormat(physicalDevice, &fbDepthFormat);

            Debug.Assert(validDepthFormat);

            // Color attachment
            var imageInfo = VkImageCreateInfo.Alloc();

            imageInfo->imageType     = VkImageType._2d;// VK_IMAGE_TYPE_2D;
            imageInfo->format        = FB_COLOR_FORMAT;
            imageInfo->extent.width  = (uint)offscreenPass.width;
            imageInfo->extent.height = (uint)offscreenPass.height;
            imageInfo->extent.depth  = 1;
            imageInfo->mipLevels     = 1;
            imageInfo->arrayLayers   = 1;
            imageInfo->samples       = VkSampleCountFlagBits._1; // VK_SAMPLE_COUNT_1_BIT;
            imageInfo->tiling        = VkImageTiling.Optimal;    // VK_IMAGE_TILING_OPTIMAL;
            // We will sample directly from the color attachment
            imageInfo->usage = VkImageUsageFlagBits.ColorAttachment | VkImageUsageFlagBits.Sampled;
            //VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;

            var memAlloc = VkMemoryAllocateInfo.Alloc();
            VkMemoryRequirements memReqs;

            {
                VkImage image;
                vkCreateImage(device, imageInfo, null, &image);
                offscreenPass.colorAttachment.image = image;
            }
            vkGetImageMemoryRequirements(device, offscreenPass.colorAttachment.image, &memReqs);
            memAlloc->allocationSize  = memReqs.size;
            memAlloc->memoryTypeIndex = vulkanDevice.getMemoryType(memReqs.memoryTypeBits,
                                                                   VkMemoryPropertyFlagBits.DeviceLocal);
            //VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
            {
                VkDeviceMemory memory;
                vkAllocateMemory(device, memAlloc, null, &memory);
                offscreenPass.colorAttachment.mem = memory;
            }
            vkBindImageMemory(device, offscreenPass.colorAttachment.image, offscreenPass.colorAttachment.mem, 0);

            var colorViewInfo = VkImageViewCreateInfo.Alloc();

            colorViewInfo->viewType                        = VkImageViewType._2d;// VK_IMAGE_VIEW_TYPE_2D;
            colorViewInfo->format                          = FB_COLOR_FORMAT;
            colorViewInfo->subresourceRange                = new VkImageSubresourceRange();
            colorViewInfo->subresourceRange.aspectMask     = VkImageAspectFlagBits.Color;// VK_IMAGE_ASPECT_COLOR_BIT;
            colorViewInfo->subresourceRange.baseMipLevel   = 0;
            colorViewInfo->subresourceRange.levelCount     = 1;
            colorViewInfo->subresourceRange.baseArrayLayer = 0;
            colorViewInfo->subresourceRange.layerCount     = 1;
            colorViewInfo->image = offscreenPass.colorAttachment.image;
            {
                VkImageView view;
                vkCreateImageView(device, colorViewInfo, null, &view);
                offscreenPass.colorAttachment.view = view;
            }

            // Create sampler to sample from the attachment in the fragment shader
            var samplerInfo = VkSamplerCreateInfo.Alloc();

            samplerInfo->magFilter     = VkFilter.Linear;                  // VK_FILTER_LINEAR;
            samplerInfo->minFilter     = VkFilter.Linear;                  // VK_FILTER_LINEAR;
            samplerInfo->mipmapMode    = VkSamplerMipmapMode.Linear;       // VK_SAMPLER_MIPMAP_MODE_LINEAR;
            samplerInfo->addressModeU  = VkSamplerAddressMode.ClampToEdge; // VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
            samplerInfo->addressModeV  = samplerInfo->addressModeU;
            samplerInfo->addressModeW  = samplerInfo->addressModeU;
            samplerInfo->mipLodBias    = 0.0f;
            samplerInfo->maxAnisotropy = 0;
            samplerInfo->minLod        = 0.0f;
            samplerInfo->maxLod        = 1.0f;
            samplerInfo->borderColor   = VkBorderColor.FloatOpaqueWhite;// VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
            {
                VkSampler sampler;
                vkCreateSampler(device, samplerInfo, null, &sampler);
                offscreenPass.sampler = sampler;
            }

            // Depth stencil attachment
            imageInfo->format = fbDepthFormat;
            imageInfo->usage  = VkImageUsageFlagBits.DepthStencilAttachment;// VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;

            {
                VkImage image;
                vkCreateImage(device, imageInfo, null, &image);
                offscreenPass.depthAttachment.image = image;
            }
            vkGetImageMemoryRequirements(device, offscreenPass.depthAttachment.image, &memReqs);
            memAlloc->allocationSize  = memReqs.size;
            memAlloc->memoryTypeIndex = vulkanDevice.getMemoryType(memReqs.memoryTypeBits,
                                                                   VkMemoryPropertyFlagBits.DeviceLocal);
            //VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
            {
                VkDeviceMemory memory;
                vkAllocateMemory(device, memAlloc, null, &memory);
                offscreenPass.depthAttachment.mem = memory;
            }
            vkBindImageMemory(device, offscreenPass.depthAttachment.image, offscreenPass.depthAttachment.mem, 0);

            var depthViewInfo = VkImageViewCreateInfo.Alloc();

            depthViewInfo->viewType                    = VkImageViewType._2d;// VK_IMAGE_VIEW_TYPE_2D;
            depthViewInfo->format                      = fbDepthFormat;
            depthViewInfo->flags                       = 0;
            depthViewInfo->subresourceRange            = new VkImageSubresourceRange();
            depthViewInfo->subresourceRange.aspectMask = VkImageAspectFlagBits.Depth | VkImageAspectFlagBits.Stencil;
            //VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
            depthViewInfo->subresourceRange.baseMipLevel   = 0;
            depthViewInfo->subresourceRange.levelCount     = 1;
            depthViewInfo->subresourceRange.baseArrayLayer = 0;
            depthViewInfo->subresourceRange.layerCount     = 1;
            depthViewInfo->image = offscreenPass.depthAttachment.image;
            {
                VkImageView view;
                vkCreateImageView(device, depthViewInfo, null, &view);
                offscreenPass.depthAttachment.view = view;
            }

            // Create a separate render pass for the offscreen rendering as it may differ from the one used for scene rendering

            var attchmentDescriptions = new VkAttachmentDescription[2];

            // Color attachment
            attchmentDescriptions[0].format         = FB_COLOR_FORMAT;
            attchmentDescriptions[0].samples        = VkSampleCountFlagBits._1;            // VK_SAMPLE_COUNT_1_BIT;
            attchmentDescriptions[0].loadOp         = VkAttachmentLoadOp.Clear;            // VK_ATTACHMENT_LOAD_OP_CLEAR;
            attchmentDescriptions[0].storeOp        = VkAttachmentStoreOp.Store;           // VK_ATTACHMENT_STORE_OP_STORE;
            attchmentDescriptions[0].stencilLoadOp  = VkAttachmentLoadOp.DontCare;         // VK_ATTACHMENT_LOAD_OP_DONT_CARE;
            attchmentDescriptions[0].stencilStoreOp = VkAttachmentStoreOp.DontCare;        // VK_ATTACHMENT_STORE_OP_DONT_CARE;
            attchmentDescriptions[0].initialLayout  = VkImageLayout.Undefined;             // VK_IMAGE_LAYOUT_UNDEFINED;
            attchmentDescriptions[0].finalLayout    = VkImageLayout.ShaderReadOnlyOptimal; // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
            // Depth attachment
            attchmentDescriptions[1].format         = fbDepthFormat;
            attchmentDescriptions[1].samples        = VkSampleCountFlagBits._1;                    // VK_SAMPLE_COUNT_1_BIT;
            attchmentDescriptions[1].loadOp         = VkAttachmentLoadOp.Clear;                    // VK_ATTACHMENT_LOAD_OP_CLEAR;
            attchmentDescriptions[1].storeOp        = VkAttachmentStoreOp.DontCare;                // VK_ATTACHMENT_STORE_OP_DONT_CARE;
            attchmentDescriptions[1].stencilLoadOp  = VkAttachmentLoadOp.DontCare;                 // VK_ATTACHMENT_LOAD_OP_DONT_CARE;
            attchmentDescriptions[1].stencilStoreOp = VkAttachmentStoreOp.DontCare;                // VK_ATTACHMENT_STORE_OP_DONT_CARE;
            attchmentDescriptions[1].initialLayout  = VkImageLayout.Undefined;                     // VK_IMAGE_LAYOUT_UNDEFINED;
            attchmentDescriptions[1].finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal; // VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

            var colorReference = new VkAttachmentReference {
                attachment = 0,
                layout     = VkImageLayout.ColorAttachmentOptimal// VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
            };
            var depthReference = new VkAttachmentReference {
                attachment = 1,
                layout     = VkImageLayout.DepthStencilAttachmentOptimal// VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
            };

            VkSubpassDescription subpassDescription = new VkSubpassDescription();

            subpassDescription.pipelineBindPoint = VkPipelineBindPoint.Graphics;// VK_PIPELINE_BIND_POINT_GRAPHICS;
            subpassDescription.colorResolveAttachments.SetColorAttachments(colorReference);
            subpassDescription.pDepthStencilAttachment = &depthReference;

            // Use subpass dependencies for layout transitions
            var dependencies = new VkSubpassDependency[2];

            dependencies[0].srcSubpass    = VK_SUBPASS_EXTERNAL;
            dependencies[0].dstSubpass    = 0;
            dependencies[0].srcStageMask  = VkPipelineStageFlagBits.BottomOfPipe;          // VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
            dependencies[0].dstStageMask  = VkPipelineStageFlagBits.ColorAttachmentOutput; // VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
            dependencies[0].srcAccessMask = VkAccessFlagBits.MemoryRead;                   // VK_ACCESS_MEMORY_READ_BIT;
            dependencies[0].dstAccessMask = VkAccessFlagBits.ColorAttachmentRead | VkAccessFlagBits.ColorAttachmentWrite;
            //VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
            dependencies[0].dependencyFlags = VkDependencyFlagBits.ByRegion;// VK_DEPENDENCY_BY_REGION_BIT;
            dependencies[1].srcSubpass      = 0;
            dependencies[1].dstSubpass      = VK_SUBPASS_EXTERNAL;
            dependencies[1].srcStageMask    = VkPipelineStageFlagBits.ColorAttachmentOutput; // VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
            dependencies[1].dstStageMask    = VkPipelineStageFlagBits.BottomOfPipe;          // VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
            dependencies[1].srcAccessMask   = VkAccessFlagBits.ColorAttachmentRead | VkAccessFlagBits.ColorAttachmentWrite;
            //VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
            dependencies[1].dstAccessMask   = VkAccessFlagBits.MemoryRead;   // VK_ACCESS_MEMORY_READ_BIT;
            dependencies[1].dependencyFlags = VkDependencyFlagBits.ByRegion; // VK_DEPENDENCY_BY_REGION_BIT;

            // Create the actual renderpass
            var renderPassInfo = VkRenderPassCreateInfo.Alloc();

            renderPassInfo->attachments  = attchmentDescriptions;
            renderPassInfo->subpasses    = subpassDescription;
            renderPassInfo->dependencies = dependencies;
            {
                VkRenderPass renderPass;
                vkCreateRenderPass(device, renderPassInfo, null, &renderPass);
                offscreenPass.renderPass = renderPass;
            }

            var attachments = new VkImageView[] {
                offscreenPass.colorAttachment.view,
                offscreenPass.depthAttachment.view
            };

            var framebufferInfo = VkFramebufferCreateInfo.Alloc();

            framebufferInfo->renderPass  = offscreenPass.renderPass;
            framebufferInfo->attachments = attachments;
            framebufferInfo->width       = (uint)offscreenPass.width;
            framebufferInfo->height      = (uint)offscreenPass.height;
            framebufferInfo->layers      = 1;
            {
                VkFramebuffer framebuffer;
                vkCreateFramebuffer(device, framebufferInfo, null, &framebuffer);
                offscreenPass.framebuffer = framebuffer;
            }

            // Fill a descriptor for later use in a descriptor set
            offscreenPass.descriptorImage.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;// VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
            offscreenPass.descriptorImage.imageView   = offscreenPass.colorAttachment.view;
            offscreenPass.descriptorImage.sampler     = offscreenPass.sampler;
        }
Ejemplo n.º 11
0
        public unsafe RenderPass(
            Device device,
            List <RenderPassAttachment> attachments,
            List <RenderPassSubPass> subPasses
            )
        {
            // update depth format to one that this device supports
            var correctDepthFormat = device.FindDepthFormat;

            for (int i = 0; i < attachments.Count; i++)
            {
                if (attachments[i].Format == RenderPassAttachment.DefaultDepth.Format)
                {
                    attachments[i] = new RenderPassAttachment
                    {
                        Format           = correctDepthFormat,
                        Clear            = attachments[i].Clear,
                        Store            = attachments[i].Store,
                        InitialLayout    = attachments[i].InitialLayout,
                        FinalLayout      = attachments[i].FinalLayout,
                        ImageUsageFlags  = attachments[i].ImageUsageFlags,
                        ImageAspectFlags = attachments[i].ImageAspectFlags
                    };
                }
            }
            _device      = device;
            _attachments = attachments;
            _subPassInfo = subPasses;
            var subPassCount = Convert.ToUInt32(subPasses.Count);

            //setup attachments
            var attachmentDescriptions = new NativeList <VkAttachmentDescription>();

            foreach (var attachment in attachments)
            {
                attachmentDescriptions.Add(new VkAttachmentDescription
                {
                    format  = attachment.Format,
                    samples = VkSampleCountFlags.Count1,
                    loadOp  = (
                        attachment.Clear ?
                        VkAttachmentLoadOp.Clear :
                        VkAttachmentLoadOp.Load
                        ),
                    storeOp = (
                        attachment.Store ?
                        VkAttachmentStoreOp.Store :
                        VkAttachmentStoreOp.DontCare
                        ),
                    stencilLoadOp  = VkAttachmentLoadOp.DontCare,
                    stencilStoreOp = VkAttachmentStoreOp.DontCare,
                    initialLayout  = attachment.InitialLayout,
                    finalLayout    = attachment.FinalLayout
                });
            }

            //setup subpasses
            var subPassInfo         = new NativeList <VkSubpassDescription>();
            var dependencies        = new NativeList <VkSubpassDependency>();
            var colorAttachmentRefs = new List <NativeList <VkAttachmentReference> >();
            var depthAttachmentRefs = new List <VkAttachmentReference>();

            foreach (var subpass in subPasses)
            {
                var colorAttachmentRef = new NativeList <VkAttachmentReference>();
                for (int i = 0; i < subpass.ColorAttachments.Count; i++)
                {
                    var colorAttachmentIndex = subpass.ColorAttachments[i];
                    colorAttachmentRef.Add(new VkAttachmentReference
                    {
                        attachment = colorAttachmentIndex,
                        layout     = attachments[Convert.ToInt32(colorAttachmentIndex)].FinalLayout
                    });
                }
                colorAttachmentRefs.Add(colorAttachmentRef);
                var depthAttachment = new NativeList <VkAttachmentReference>();
                if (subpass.DepthAttachments != null)
                {
                    var depthAttachmentRef = new VkAttachmentReference
                    {
                        attachment = (uint)subpass.DepthAttachments,
                        layout     = attachments[Convert.ToInt32(subpass.DepthAttachments)].FinalLayout
                    };
                    depthAttachmentRefs.Add(depthAttachmentRef);
                    depthAttachment.Add(depthAttachmentRef);
                }
                subPassInfo.Add(new VkSubpassDescription
                {
                    pipelineBindPoint       = subpass.BindPoint,
                    colorAttachmentCount    = colorAttachmentRef.Count,
                    pColorAttachments       = (VkAttachmentReference *)colorAttachmentRef.Data.ToPointer(),
                    pDepthStencilAttachment = (
                        depthAttachment.Count != 1 ?
                        null :
                        (VkAttachmentReference *)depthAttachment.Data.ToPointer()
                        )
                });
                dependencies.Add(new VkSubpassDependency
                {
                    srcSubpass   = 0,
                    dstSubpass   = 0,
                    srcStageMask = (
                        VkPipelineStageFlags.ColorAttachmentOutput |
                        VkPipelineStageFlags.EarlyFragmentTests
                        ),
                    srcAccessMask = 0,
                    dstStageMask  = (
                        VkPipelineStageFlags.ColorAttachmentOutput |
                        VkPipelineStageFlags.EarlyFragmentTests
                        ),
                    dstAccessMask = subpass.DepthAttachments != null ? (
                        VkAccessFlags.ColorAttachmentWrite |
                        VkAccessFlags.DepthStencilAttachmentWrite
                        ) : VkAccessFlags.ColorAttachmentWrite
                });
            }

            var renderPassInfo = new VkRenderPassCreateInfo
            {
                sType           = VkStructureType.RenderPassCreateInfo,
                attachmentCount = attachmentDescriptions.Count,
                pAttachments    = (VkAttachmentDescription *)attachmentDescriptions.Data.ToPointer(),
                subpassCount    = subPassCount,
                pSubpasses      = (VkSubpassDescription *)subPassInfo.Data.ToPointer(),
                dependencyCount = dependencies.Count,
                pDependencies   = (VkSubpassDependency *)dependencies.Data.ToPointer()
            };

            VkRenderPass renderPass;

            if (VulkanNative.vkCreateRenderPass(
                    device.Handle,
                    &renderPassInfo,
                    null,
                    &renderPass
                    ) != VkResult.Success)
            {
                throw new Exception("failed to create render pass");
            }
            _handle = renderPass;
        }
Ejemplo n.º 12
0
        public VkFramebuffer(VkGraphicsDevice gd, ref FramebufferDescription description)
            : base(description.DepthTarget, description.ColorTargets)
        {
            _gd = gd;

            VkRenderPassCreateInfo renderPassCI = VkRenderPassCreateInfo.New();

            StackList <VkAttachmentDescription> attachments = new StackList <VkAttachmentDescription>();

            uint colorAttachmentCount = (uint)ColorTextures.Count;
            StackList <VkAttachmentDescription> colorAttachmentDescriptions = new StackList <VkAttachmentDescription>();
            StackList <VkAttachmentReference>   colorAttachmentRefs         = new StackList <VkAttachmentReference>();

            for (int i = 0; i < colorAttachmentCount; i++)
            {
                VkTexture vkColorTex = Util.AssertSubtype <Texture, VkTexture>(ColorTextures[i]);
                VkAttachmentDescription colorAttachmentDesc = new VkAttachmentDescription();
                colorAttachmentDesc.format         = vkColorTex.VkFormat;
                colorAttachmentDesc.samples        = VkSampleCountFlags.Count1;
                colorAttachmentDesc.loadOp         = VkAttachmentLoadOp.DontCare;
                colorAttachmentDesc.storeOp        = VkAttachmentStoreOp.Store;
                colorAttachmentDesc.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                colorAttachmentDesc.stencilStoreOp = VkAttachmentStoreOp.DontCare;
                colorAttachmentDesc.initialLayout  = VkImageLayout.Undefined;
                colorAttachmentDesc.finalLayout    = VkImageLayout.PresentSrcKHR;
                colorAttachmentDescriptions.Add(colorAttachmentDesc);
                attachments.Add(colorAttachmentDesc);

                VkAttachmentReference colorAttachmentRef = new VkAttachmentReference();
                colorAttachmentRef.attachment = (uint)i;
                colorAttachmentRef.layout     = VkImageLayout.ColorAttachmentOptimal;
                colorAttachmentRefs.Add(colorAttachmentRef);
            }

            VkTexture vkDepthTex = Util.AssertSubtype <Texture, VkTexture>(DepthTexture);
            VkAttachmentDescription depthAttachmentDesc = new VkAttachmentDescription();
            VkAttachmentReference   depthAttachmentRef  = new VkAttachmentReference();

            if (vkDepthTex != null)
            {
                depthAttachmentDesc.format         = vkDepthTex.VkFormat;
                depthAttachmentDesc.samples        = VkSampleCountFlags.Count1;
                depthAttachmentDesc.loadOp         = VkAttachmentLoadOp.DontCare;
                depthAttachmentDesc.storeOp        = VkAttachmentStoreOp.Store;
                depthAttachmentDesc.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                depthAttachmentDesc.stencilStoreOp = VkAttachmentStoreOp.DontCare;
                depthAttachmentDesc.initialLayout  = VkImageLayout.Undefined;
                depthAttachmentDesc.finalLayout    = VkImageLayout.ShaderReadOnlyOptimal;

                depthAttachmentRef.attachment = (uint)description.ColorTargets.Length;
                depthAttachmentRef.layout     = VkImageLayout.DepthStencilAttachmentOptimal;
            }

            VkSubpassDescription subpass = new VkSubpassDescription();

            subpass.pipelineBindPoint = VkPipelineBindPoint.Graphics;
            if (ColorTextures.Count > 0)
            {
                subpass.colorAttachmentCount = colorAttachmentCount;
                subpass.pColorAttachments    = (VkAttachmentReference *)colorAttachmentRefs.Data;
            }

            if (DepthTexture != null)
            {
                subpass.pDepthStencilAttachment = &depthAttachmentRef;
                attachments.Add(depthAttachmentDesc);
            }

            VkSubpassDependency subpassDependency = new VkSubpassDependency();

            subpassDependency.srcSubpass    = SubpassExternal;
            subpassDependency.srcStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite;
            if (DepthTexture != null)
            {
                subpassDependency.dstAccessMask |= VkAccessFlags.DepthStencilAttachmentRead | VkAccessFlags.DepthStencilAttachmentWrite;
            }

            renderPassCI.attachmentCount = attachments.Count;
            renderPassCI.pAttachments    = (VkAttachmentDescription *)attachments.Data;
            renderPassCI.subpassCount    = 1;
            renderPassCI.pSubpasses      = &subpass;
            renderPassCI.dependencyCount = 1;
            renderPassCI.pDependencies   = &subpassDependency;

            VkResult creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPass);

            CheckResult(creationResult);

            VkFramebufferCreateInfo fbCI = VkFramebufferCreateInfo.New();
            uint fbAttachmentsCount      = (uint)description.ColorTargets.Length;

            if (description.DepthTarget != null)
            {
                fbAttachmentsCount += 1;
            }

            VkImageView *fbAttachments = stackalloc VkImageView[(int)fbAttachmentsCount];

            for (int i = 0; i < fbAttachmentsCount - 1; i++)
            {
                Texture               colorTarget   = description.ColorTargets[i];
                VkTexture             vkColorTarget = Util.AssertSubtype <Texture, VkTexture>(colorTarget);
                VkImageViewCreateInfo imageViewCI   = VkImageViewCreateInfo.New();
                imageViewCI.image            = vkColorTarget.DeviceImage;
                imageViewCI.format           = vkColorTarget.VkFormat;
                imageViewCI.viewType         = VkImageViewType.Image2D;
                imageViewCI.subresourceRange = new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, 1, 0, 1);
                VkImageView *dest   = (fbAttachments + i);
                VkResult     result = vkCreateImageView(_gd.Device, ref imageViewCI, null, dest);
                CheckResult(result);
                _attachmentViews.Add(*dest);
            }

            // Depth
            if (description.DepthTarget != null)
            {
                VkTexture             vkDepthTarget = Util.AssertSubtype <Texture, VkTexture>(description.DepthTarget);
                VkImageViewCreateInfo depthViewCI   = VkImageViewCreateInfo.New();
                depthViewCI.image            = vkDepthTarget.DeviceImage;
                depthViewCI.format           = vkDepthTarget.VkFormat;
                depthViewCI.viewType         = VkImageViewType.Image2D;
                depthViewCI.subresourceRange = new VkImageSubresourceRange(VkImageAspectFlags.Depth, 0, 1, 0, 1);
                VkImageView *dest   = (fbAttachments + (fbAttachmentsCount - 1));
                VkResult     result = vkCreateImageView(_gd.Device, ref depthViewCI, null, dest);
                CheckResult(result);
                _attachmentViews.Add(*dest);
            }

            if (ColorTextures.Count > 0)
            {
                fbCI.width  = ColorTextures[0].Width;
                fbCI.height = ColorTextures[0].Height;
            }
            else if (vkDepthTex != null)
            {
                fbCI.width  = vkDepthTex.Width;
                fbCI.height = vkDepthTex.Height;
            }

            fbCI.attachmentCount = fbAttachmentsCount;
            fbCI.pAttachments    = fbAttachments;
            fbCI.layers          = 1;
            fbCI.renderPass      = _renderPass;

            creationResult = vkCreateFramebuffer(_gd.Device, ref fbCI, null, out _deviceFramebuffer);
            CheckResult(creationResult);
        }
Ejemplo n.º 13
0
 public override VkResult CreateRenderPass(VkRenderPassCreateInfo renderPassInfo, out VkRenderPass renderPass)
 {
     renderPass = new SoftwareRenderPass(this, renderPassInfo);
     return(VkResult.VK_SUCCESS);
 }
Ejemplo n.º 14
0
 public SoftwareRenderPass(SoftwareDevice device, VkRenderPassCreateInfo createInfo)
 {
     this.m_device     = device;
     this.m_createInfo = createInfo;
 }
Ejemplo n.º 15
0
        void CreateRenderPass()
        {
            var colorAttachment = new VkAttachmentDescription();

            colorAttachment.format         = swapchainImageFormat;
            colorAttachment.samples        = CSGL.Vulkan.VkSampleCountFlags._1_Bit;
            colorAttachment.loadOp         = CSGL.Vulkan.VkAttachmentLoadOp.Clear;
            colorAttachment.storeOp        = CSGL.Vulkan.VkAttachmentStoreOp.Store;
            colorAttachment.stencilLoadOp  = CSGL.Vulkan.VkAttachmentLoadOp.DontCare;
            colorAttachment.stencilStoreOp = CSGL.Vulkan.VkAttachmentStoreOp.DontCare;
            colorAttachment.initialLayout  = CSGL.Vulkan.VkImageLayout.Undefined;
            colorAttachment.finalLayout    = CSGL.Vulkan.VkImageLayout.PresentSrcKhr;

            var colorAttachmentNative = new Native <VkAttachmentDescription>(colorAttachment);

            var colorAttachmentRef = new VkAttachmentReference();

            colorAttachmentRef.attachment = 0;
            colorAttachmentRef.layout     = CSGL.Vulkan.VkImageLayout.ColorAttachmentOptimal;

            var colorAttachmentRefNative = new Native <VkAttachmentReference>(colorAttachmentRef);

            var subpass = new VkSubpassDescription();

            subpass.pipelineBindPoint    = CSGL.Vulkan.VkPipelineBindPoint.Graphics;
            subpass.colorAttachmentCount = 1;
            subpass.pColorAttachments    = colorAttachmentRefNative.Address;

            var subpassNative = new Native <VkSubpassDescription>(subpass);

            var dependency = new VkSubpassDependency();

            dependency.srcSubpass    = uint.MaxValue; //VK_SUBPASS_EXTERNAL
            dependency.dstSubpass    = 0;
            dependency.srcStageMask  = CSGL.Vulkan.VkPipelineStageFlags.BottomOfPipeBit;
            dependency.srcAccessMask = CSGL.Vulkan.VkAccessFlags.MemoryReadBit;
            dependency.dstStageMask  = CSGL.Vulkan.VkPipelineStageFlags.ColorAttachmentOutputBit;
            dependency.dstAccessMask = CSGL.Vulkan.VkAccessFlags.ColorAttachmentReadBit
                                       | CSGL.Vulkan.VkAccessFlags.ColorAttachmentWriteBit;

            var dependencyNative = new Native <VkSubpassDependency>(dependency);

            var info = new VkRenderPassCreateInfo();

            info.sType           = CSGL.Vulkan.VkStructureType.RenderPassCreateInfo;
            info.attachmentCount = 1;
            info.pAttachments    = colorAttachmentNative.Address;
            info.subpassCount    = 1;
            info.pSubpasses      = subpassNative.Address;
            info.dependencyCount = 1;
            info.pDependencies   = dependencyNative.Address;

            if (renderPass != VkRenderPass.Null)
            {
                VK.DestroyRenderPass(device, renderPass, alloc);
            }

            var result = VK.CreateRenderPass(device, ref info, alloc, out renderPass);

            colorAttachmentNative.Dispose();
            colorAttachmentRefNative.Dispose();
            subpassNative.Dispose();
            dependencyNative.Dispose();
        }
Ejemplo n.º 16
0
        public VkPipeline(VkGraphicsDevice gd, ref PipelineDescription description)
        {
            _gd = gd;

            VkGraphicsPipelineCreateInfo pipelineCI = VkGraphicsPipelineCreateInfo.New();

            // Blend State
            VkPipelineColorBlendStateCreateInfo blendStateCI = VkPipelineColorBlendStateCreateInfo.New();
            int attachmentsCount = description.BlendState.AttachmentStates.Length;
            VkPipelineColorBlendAttachmentState *attachmentsPtr
                = stackalloc VkPipelineColorBlendAttachmentState[attachmentsCount];

            for (int i = 0; i < attachmentsCount; i++)
            {
                BlendAttachmentDescription          vdDesc          = description.BlendState.AttachmentStates[i];
                VkPipelineColorBlendAttachmentState attachmentState = new VkPipelineColorBlendAttachmentState();
                attachmentState.srcColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceColorFactor);
                attachmentState.dstColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationColorFactor);
                attachmentState.colorBlendOp        = VkFormats.VdToVkBlendOp(vdDesc.ColorFunction);
                attachmentState.srcAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceAlphaFactor);
                attachmentState.dstAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationAlphaFactor);
                attachmentState.alphaBlendOp        = VkFormats.VdToVkBlendOp(vdDesc.AlphaFunction);
                attachmentState.blendEnable         = vdDesc.BlendEnabled;
                attachmentState.colorWriteMask      = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A;
                attachmentsPtr[i] = attachmentState;
            }

            blendStateCI.attachmentCount = (uint)attachmentsCount;
            blendStateCI.pAttachments    = attachmentsPtr;
            RgbaFloat blendFactor = description.BlendState.BlendFactor;

            blendStateCI.blendConstants_0 = blendFactor.R;
            blendStateCI.blendConstants_1 = blendFactor.G;
            blendStateCI.blendConstants_2 = blendFactor.B;
            blendStateCI.blendConstants_3 = blendFactor.A;

            pipelineCI.pColorBlendState = &blendStateCI;

            // Rasterizer State
            RasterizerStateDescription             rsDesc = description.RasterizerState;
            VkPipelineRasterizationStateCreateInfo rsCI   = VkPipelineRasterizationStateCreateInfo.New();

            rsCI.cullMode         = VkFormats.VdToVkCullMode(rsDesc.CullMode);
            rsCI.polygonMode      = VkFormats.VdToVkPolygonMode(rsDesc.FillMode);
            rsCI.depthClampEnable = !rsDesc.DepthClipEnabled;
            rsCI.frontFace        = VkFrontFace.Clockwise;
            rsCI.lineWidth        = 1f;

            pipelineCI.pRasterizationState = &rsCI;

            // Dynamic State
            VkPipelineDynamicStateCreateInfo dynamicStateCI = VkPipelineDynamicStateCreateInfo.New();
            VkDynamicState *dynamicStates = stackalloc VkDynamicState[2];

            dynamicStates[0] = VkDynamicState.Viewport;
            dynamicStates[1] = VkDynamicState.Scissor;
            dynamicStateCI.dynamicStateCount = 2;
            dynamicStateCI.pDynamicStates    = dynamicStates;

            pipelineCI.pDynamicState = &dynamicStateCI;

            // Depth Stencil State
            DepthStencilStateDescription          vdDssDesc = description.DepthStencilState;
            VkPipelineDepthStencilStateCreateInfo dssCI     = VkPipelineDepthStencilStateCreateInfo.New();

            dssCI.depthWriteEnable = vdDssDesc.DepthWriteEnabled;
            dssCI.depthTestEnable  = vdDssDesc.DepthTestEnabled;
            dssCI.depthCompareOp   = VkFormats.VdToVkCompareOp(vdDssDesc.ComparisonKind);

            pipelineCI.pDepthStencilState = &dssCI;

            // Multisample
            VkPipelineMultisampleStateCreateInfo multisampleCI = VkPipelineMultisampleStateCreateInfo.New();

            multisampleCI.rasterizationSamples = VkSampleCountFlags.Count1;

            pipelineCI.pMultisampleState = &multisampleCI;

            // Input Assembly
            VkPipelineInputAssemblyStateCreateInfo inputAssemblyCI = VkPipelineInputAssemblyStateCreateInfo.New();

            inputAssemblyCI.topology = VkFormats.VdToVkPrimitiveTopology(description.PrimitiveTopology);

            pipelineCI.pInputAssemblyState = &inputAssemblyCI;

            // Vertex Input State
            VkPipelineVertexInputStateCreateInfo vertexInputCI = VkPipelineVertexInputStateCreateInfo.New();

            VertexLayoutDescription[] inputDescriptions = description.ShaderSet.VertexLayouts;
            uint bindingCount   = (uint)inputDescriptions.Length;
            uint attributeCount = 0;

            for (int i = 0; i < inputDescriptions.Length; i++)
            {
                attributeCount += (uint)inputDescriptions[i].Elements.Length;
            }
            VkVertexInputBindingDescription *  bindingDescs   = stackalloc VkVertexInputBindingDescription[(int)bindingCount];
            VkVertexInputAttributeDescription *attributeDescs = stackalloc VkVertexInputAttributeDescription[(int)attributeCount];

            int targetIndex    = 0;
            int targetLocation = 0;

            for (int binding = 0; binding < inputDescriptions.Length; binding++)
            {
                VertexLayoutDescription inputDesc = inputDescriptions[binding];
                bindingDescs[targetIndex] = new VkVertexInputBindingDescription()
                {
                    binding   = (uint)binding,
                    inputRate = (inputDesc.Elements[0].InstanceStepRate != 0) ? VkVertexInputRate.Instance : VkVertexInputRate.Vertex,
                    stride    = inputDesc.Stride
                };

                uint currentOffset = 0;
                for (int location = 0; location < inputDesc.Elements.Length; location++)
                {
                    VertexElementDescription inputElement = inputDesc.Elements[location];

                    attributeDescs[targetIndex] = new VkVertexInputAttributeDescription()
                    {
                        format   = VkFormats.VdToVkVertexElementFormat(inputElement.Format),
                        binding  = (uint)binding,
                        location = (uint)(targetLocation + location),
                        offset   = currentOffset
                    };

                    targetIndex   += 1;
                    currentOffset += FormatHelpers.GetSizeInBytes(inputElement.Format);
                }

                targetLocation += inputDesc.Elements.Length;
            }

            vertexInputCI.vertexBindingDescriptionCount   = bindingCount;
            vertexInputCI.pVertexBindingDescriptions      = bindingDescs;
            vertexInputCI.vertexAttributeDescriptionCount = attributeCount;
            vertexInputCI.pVertexAttributeDescriptions    = attributeDescs;

            pipelineCI.pVertexInputState = &vertexInputCI;

            // Shader Stage
            ShaderStageDescription[] stageDescs = description.ShaderSet.ShaderStages;
            StackList <VkPipelineShaderStageCreateInfo> stages = new StackList <VkPipelineShaderStageCreateInfo>();

            foreach (ShaderStageDescription stageDesc in stageDescs)
            {
                VkShader vkShader = Util.AssertSubtype <Shader, VkShader>(stageDesc.Shader);
                VkPipelineShaderStageCreateInfo stageCI = VkPipelineShaderStageCreateInfo.New();
                stageCI.module = vkShader.ShaderModule;
                stageCI.stage  = VkFormats.VdToVkShaderStages(stageDesc.Stage);
                stageCI.pName  = CommonStrings.main; // Meh
                stages.Add(stageCI);
            }

            pipelineCI.stageCount = stages.Count;
            pipelineCI.pStages    = (VkPipelineShaderStageCreateInfo *)stages.Data;

            // ViewportState
            VkPipelineViewportStateCreateInfo viewportStateCI = VkPipelineViewportStateCreateInfo.New();

            viewportStateCI.viewportCount = 1;
            viewportStateCI.scissorCount  = 1;

            pipelineCI.pViewportState = &viewportStateCI;

            // Pipeline Layout
            ResourceLayout[]           resourceLayouts  = description.ResourceLayouts;
            VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New();

            pipelineLayoutCI.setLayoutCount = (uint)resourceLayouts.Length;
            VkDescriptorSetLayout *dsls = stackalloc VkDescriptorSetLayout[resourceLayouts.Length];

            for (int i = 0; i < resourceLayouts.Length; i++)
            {
                dsls[i] = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(resourceLayouts[i]).DescriptorSetLayout;
            }
            pipelineLayoutCI.pSetLayouts = dsls;

            vkCreatePipelineLayout(_gd.Device, ref pipelineLayoutCI, null, out _pipelineLayout);
            pipelineCI.layout = _pipelineLayout;

            // Create fake RenderPass for compatibility.
            VkRenderPassCreateInfo renderPassCI = VkRenderPassCreateInfo.New();
            OutputDescription      outputDesc   = description.Outputs;

            if (outputDesc.ColorAttachments.Length > 1)
            {
                throw new NotImplementedException("Laziness");
            }

            VkAttachmentDescription colorAttachmentDesc = new VkAttachmentDescription();

            colorAttachmentDesc.format = outputDesc.ColorAttachments.Length > 0
                ? VkFormats.VdToVkPixelFormat(outputDesc.ColorAttachments[0].Format) : 0;
            colorAttachmentDesc.samples        = VkSampleCountFlags.Count1;
            colorAttachmentDesc.loadOp         = VkAttachmentLoadOp.Clear;
            colorAttachmentDesc.storeOp        = VkAttachmentStoreOp.Store;
            colorAttachmentDesc.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
            colorAttachmentDesc.stencilStoreOp = VkAttachmentStoreOp.DontCare;
            colorAttachmentDesc.initialLayout  = VkImageLayout.Undefined;
            colorAttachmentDesc.finalLayout    = VkImageLayout.PresentSrcKHR;

            VkAttachmentReference colorAttachmentRef = new VkAttachmentReference();

            colorAttachmentRef.attachment = 0;
            colorAttachmentRef.layout     = VkImageLayout.ColorAttachmentOptimal;

            VkAttachmentDescription depthAttachmentDesc = new VkAttachmentDescription();
            VkAttachmentReference   depthAttachmentRef  = new VkAttachmentReference();

            if (outputDesc.DepthAttachment != null)
            {
                depthAttachmentDesc.format         = VkFormats.VdToVkPixelFormat(outputDesc.DepthAttachment.Value.Format, toDepthFormat: true);
                depthAttachmentDesc.samples        = VkSampleCountFlags.Count1;
                depthAttachmentDesc.loadOp         = VkAttachmentLoadOp.Clear;
                depthAttachmentDesc.storeOp        = VkAttachmentStoreOp.Store;
                depthAttachmentDesc.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                depthAttachmentDesc.stencilStoreOp = VkAttachmentStoreOp.DontCare;
                depthAttachmentDesc.initialLayout  = VkImageLayout.Undefined;
                depthAttachmentDesc.finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal;

                depthAttachmentRef.attachment = outputDesc.ColorAttachments.Length == 0 ? 0u : 1u;
                depthAttachmentRef.layout     = VkImageLayout.DepthStencilAttachmentOptimal;
            }

            VkSubpassDescription subpass = new VkSubpassDescription();
            StackList <VkAttachmentDescription, Size512Bytes> attachments = new StackList <VkAttachmentDescription, Size512Bytes>();

            subpass.pipelineBindPoint = VkPipelineBindPoint.Graphics;
            if (outputDesc.ColorAttachments.Length > 0)
            {
                subpass.colorAttachmentCount = 1;
                subpass.pColorAttachments    = &colorAttachmentRef;
                attachments.Add(colorAttachmentDesc);
            }

            if (outputDesc.DepthAttachment != null)
            {
                subpass.pDepthStencilAttachment = &depthAttachmentRef;
                attachments.Add(depthAttachmentDesc);
            }

            VkSubpassDependency subpassDependency = new VkSubpassDependency();

            subpassDependency.srcSubpass    = SubpassExternal;
            subpassDependency.srcStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite;
            if (outputDesc.DepthAttachment != null)
            {
                subpassDependency.dstAccessMask |= VkAccessFlags.DepthStencilAttachmentRead | VkAccessFlags.DepthStencilAttachmentWrite;
            }

            renderPassCI.attachmentCount = attachments.Count;
            renderPassCI.pAttachments    = (VkAttachmentDescription *)attachments.Data;
            renderPassCI.subpassCount    = 1;
            renderPassCI.pSubpasses      = &subpass;
            renderPassCI.dependencyCount = 1;
            renderPassCI.pDependencies   = &subpassDependency;

            VkResult creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPass);

            CheckResult(creationResult);

            pipelineCI.renderPass = _renderPass;

            VkResult result = vkCreateGraphicsPipelines(_gd.Device, VkPipelineCache.Null, 1, ref pipelineCI, null, out _devicePipeline);

            CheckResult(result);

            ResourceSetCount = (uint)description.ResourceLayouts.Length;
        }
Ejemplo n.º 17
0
 public override VkResult CreateRenderPass(VkRenderPassCreateInfo renderPassInfo, out VkRenderPass renderPass)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 18
0
        static VkRenderPass CreateRenderPass(VkDevice device)
        {
            VkAttachmentDescription colourAttachmentDescription = new VkAttachmentDescription();

            colourAttachmentDescription.format         = surfaceFormat.format;
            colourAttachmentDescription.samples        = VkSampleCountFlags.Count1;
            colourAttachmentDescription.loadOp         = VkAttachmentLoadOp.Clear;
            colourAttachmentDescription.storeOp        = VkAttachmentStoreOp.Store;
            colourAttachmentDescription.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
            colourAttachmentDescription.stencilStoreOp = VkAttachmentStoreOp.DontCare;
            colourAttachmentDescription.initialLayout  = VkImageLayout.ColorAttachmentOptimal;
            colourAttachmentDescription.finalLayout    = VkImageLayout.PresentSrcKHR;

            VkAttachmentDescription depthAttachment = new VkAttachmentDescription();

            depthAttachment.format         = VkFormat.D32Sfloat;
            depthAttachment.samples        = VkSampleCountFlags.Count1;
            depthAttachment.loadOp         = VkAttachmentLoadOp.Clear;
            depthAttachment.storeOp        = VkAttachmentStoreOp.DontCare;
            depthAttachment.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
            depthAttachment.stencilStoreOp = VkAttachmentStoreOp.DontCare;
            depthAttachment.initialLayout  = VkImageLayout.Undefined;
            depthAttachment.finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal;


            VkAttachmentReference attachmentReference = new VkAttachmentReference();

            attachmentReference.attachment = 0;
            attachmentReference.layout     = VkImageLayout.ColorAttachmentOptimal;

            VkAttachmentReference depthAttachmentReference = new VkAttachmentReference();

            depthAttachmentReference.attachment = 1;
            depthAttachmentReference.layout     = VkImageLayout.DepthStencilAttachmentOptimal;

            VkSubpassDescription subpassDescription = new VkSubpassDescription();

            subpassDescription.pipelineBindPoint       = VkPipelineBindPoint.Graphics;
            subpassDescription.colorAttachmentCount    = 1;
            subpassDescription.pColorAttachments       = &attachmentReference;
            subpassDescription.pDepthStencilAttachment = &depthAttachmentReference;

            VkAttachmentDescription[] attachmentDescriptions = new VkAttachmentDescription[] {
                colourAttachmentDescription,
                depthAttachment
            };
            VkRenderPassCreateInfo pCreateInfo = VkRenderPassCreateInfo.New();

            pCreateInfo.attachmentCount = (uint)attachmentDescriptions.Length;

            fixed(VkAttachmentDescription *ptr = attachmentDescriptions)
            pCreateInfo.pAttachments = ptr;

            pCreateInfo.subpassCount = 1;
            pCreateInfo.pSubpasses   = &subpassDescription;


            VkRenderPass pass = VkRenderPass.Null;

            Assert(vkCreateRenderPass(device, &pCreateInfo, null, &pass));
            return(pass);
        }
Ejemplo n.º 19
0
        // Setup the offscreen framebuffer for rendering the blurred scene
        // The color attachment of this framebuffer will then be used to sample frame in the fragment shader of the final pass
        void prepareOffscreen()
        {
            offscreenPass.width  = FB_DIM;
            offscreenPass.height = FB_DIM;

            // Find a suitable depth format
            VkFormat fbDepthFormat;
            VkBool32 validDepthFormat = Tools.getSupportedDepthFormat(physicalDevice, &fbDepthFormat);

            Debug.Assert(validDepthFormat);

            // Color attachment
            VkImageCreateInfo image = Initializers.imageCreateInfo();

            image.imageType     = VK_IMAGE_TYPE_2D;
            image.format        = FB_COLOR_FORMAT;
            image.extent.width  = (uint)offscreenPass.width;
            image.extent.height = (uint)offscreenPass.height;
            image.extent.depth  = 1;
            image.mipLevels     = 1;
            image.arrayLayers   = 1;
            image.samples       = VK_SAMPLE_COUNT_1_BIT;
            image.tiling        = VK_IMAGE_TILING_OPTIMAL;
            // We will sample directly from the color attachment
            image.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;

            VkMemoryAllocateInfo memAlloc = Initializers.memoryAllocateInfo();
            VkMemoryRequirements memReqs;

            Util.CheckResult(vkCreateImage(device, &image, null, out offscreenPass.color.image));
            vkGetImageMemoryRequirements(device, offscreenPass.color.image, &memReqs);
            memAlloc.allocationSize  = memReqs.size;
            memAlloc.memoryTypeIndex = vulkanDevice.getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
            Util.CheckResult(vkAllocateMemory(device, &memAlloc, null, out offscreenPass.color.mem));
            Util.CheckResult(vkBindImageMemory(device, offscreenPass.color.image, offscreenPass.color.mem, 0));

            VkImageViewCreateInfo colorImageView = Initializers.imageViewCreateInfo();

            colorImageView.viewType                        = VK_IMAGE_VIEW_TYPE_2D;
            colorImageView.format                          = FB_COLOR_FORMAT;
            colorImageView.subresourceRange                = new VkImageSubresourceRange();
            colorImageView.subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
            colorImageView.subresourceRange.baseMipLevel   = 0;
            colorImageView.subresourceRange.levelCount     = 1;
            colorImageView.subresourceRange.baseArrayLayer = 0;
            colorImageView.subresourceRange.layerCount     = 1;
            colorImageView.image = offscreenPass.color.image;
            Util.CheckResult(vkCreateImageView(device, &colorImageView, null, out offscreenPass.color.view));

            // Create sampler to sample from the attachment in the fragment shader
            VkSamplerCreateInfo samplerInfo = Initializers.samplerCreateInfo();

            samplerInfo.magFilter     = VK_FILTER_LINEAR;
            samplerInfo.minFilter     = VK_FILTER_LINEAR;
            samplerInfo.mipmapMode    = VK_SAMPLER_MIPMAP_MODE_LINEAR;
            samplerInfo.addressModeU  = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
            samplerInfo.addressModeV  = samplerInfo.addressModeU;
            samplerInfo.addressModeW  = samplerInfo.addressModeU;
            samplerInfo.mipLodBias    = 0.0f;
            samplerInfo.maxAnisotropy = 0;
            samplerInfo.minLod        = 0.0f;
            samplerInfo.maxLod        = 1.0f;
            samplerInfo.borderColor   = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
            Util.CheckResult(vkCreateSampler(device, &samplerInfo, null, out offscreenPass.sampler));

            // Depth stencil attachment
            image.format = fbDepthFormat;
            image.usage  = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;

            Util.CheckResult(vkCreateImage(device, &image, null, out offscreenPass.depth.image));
            vkGetImageMemoryRequirements(device, offscreenPass.depth.image, &memReqs);
            memAlloc.allocationSize  = memReqs.size;
            memAlloc.memoryTypeIndex = vulkanDevice.getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
            Util.CheckResult(vkAllocateMemory(device, &memAlloc, null, out offscreenPass.depth.mem));
            Util.CheckResult(vkBindImageMemory(device, offscreenPass.depth.image, offscreenPass.depth.mem, 0));

            VkImageViewCreateInfo depthStencilView = Initializers.imageViewCreateInfo();

            depthStencilView.viewType                        = VK_IMAGE_VIEW_TYPE_2D;
            depthStencilView.format                          = fbDepthFormat;
            depthStencilView.flags                           = 0;
            depthStencilView.subresourceRange                = new VkImageSubresourceRange();
            depthStencilView.subresourceRange.aspectMask     = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
            depthStencilView.subresourceRange.baseMipLevel   = 0;
            depthStencilView.subresourceRange.levelCount     = 1;
            depthStencilView.subresourceRange.baseArrayLayer = 0;
            depthStencilView.subresourceRange.layerCount     = 1;
            depthStencilView.image                           = offscreenPass.depth.image;
            Util.CheckResult(vkCreateImageView(device, &depthStencilView, null, out offscreenPass.depth.view));

            // Create a separate render pass for the offscreen rendering as it may differ from the one used for scene rendering

            FixedArray2 <VkAttachmentDescription> attchmentDescriptions = new FixedArray2 <VkAttachmentDescription>();

            // Color attachment
            attchmentDescriptions.First.format         = FB_COLOR_FORMAT;
            attchmentDescriptions.First.samples        = VK_SAMPLE_COUNT_1_BIT;
            attchmentDescriptions.First.loadOp         = VK_ATTACHMENT_LOAD_OP_CLEAR;
            attchmentDescriptions.First.storeOp        = VK_ATTACHMENT_STORE_OP_STORE;
            attchmentDescriptions.First.stencilLoadOp  = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
            attchmentDescriptions.First.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
            attchmentDescriptions.First.initialLayout  = VK_IMAGE_LAYOUT_UNDEFINED;
            attchmentDescriptions.First.finalLayout    = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
            // Depth attachment
            attchmentDescriptions.Second.format         = fbDepthFormat;
            attchmentDescriptions.Second.samples        = VK_SAMPLE_COUNT_1_BIT;
            attchmentDescriptions.Second.loadOp         = VK_ATTACHMENT_LOAD_OP_CLEAR;
            attchmentDescriptions.Second.storeOp        = VK_ATTACHMENT_STORE_OP_DONT_CARE;
            attchmentDescriptions.Second.stencilLoadOp  = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
            attchmentDescriptions.Second.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
            attchmentDescriptions.Second.initialLayout  = VK_IMAGE_LAYOUT_UNDEFINED;
            attchmentDescriptions.Second.finalLayout    = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

            VkAttachmentReference colorReference = new VkAttachmentReference {
                attachment = 0, layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
            };
            VkAttachmentReference depthReference = new VkAttachmentReference {
                attachment = 1, layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
            };

            VkSubpassDescription subpassDescription = new VkSubpassDescription();

            subpassDescription.pipelineBindPoint       = VK_PIPELINE_BIND_POINT_GRAPHICS;
            subpassDescription.colorAttachmentCount    = 1;
            subpassDescription.pColorAttachments       = &colorReference;
            subpassDescription.pDepthStencilAttachment = &depthReference;

            // Use subpass dependencies for layout transitions
            FixedArray2 <VkSubpassDependency> dependencies = new FixedArray2 <VkSubpassDependency>();

            dependencies.First.srcSubpass      = VK_SUBPASS_EXTERNAL;
            dependencies.First.dstSubpass      = 0;
            dependencies.First.srcStageMask    = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
            dependencies.First.dstStageMask    = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
            dependencies.First.srcAccessMask   = VK_ACCESS_MEMORY_READ_BIT;
            dependencies.First.dstAccessMask   = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
            dependencies.First.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

            dependencies.Second.srcSubpass      = 0;
            dependencies.Second.dstSubpass      = VK_SUBPASS_EXTERNAL;
            dependencies.Second.srcStageMask    = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
            dependencies.Second.dstStageMask    = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
            dependencies.Second.srcAccessMask   = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
            dependencies.Second.dstAccessMask   = VK_ACCESS_MEMORY_READ_BIT;
            dependencies.Second.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

            // Create the actual renderpass
            VkRenderPassCreateInfo renderPassInfo = VkRenderPassCreateInfo.New();

            renderPassInfo.attachmentCount = attchmentDescriptions.Count;
            renderPassInfo.pAttachments    = &attchmentDescriptions.First;
            renderPassInfo.subpassCount    = 1;
            renderPassInfo.pSubpasses      = &subpassDescription;
            renderPassInfo.dependencyCount = dependencies.Count;
            renderPassInfo.pDependencies   = &dependencies.First;

            Util.CheckResult(vkCreateRenderPass(device, &renderPassInfo, null, out offscreenPass.renderPass));

            FixedArray2 <VkImageView> attachments = new FixedArray2 <VkImageView>(offscreenPass.color.view, offscreenPass.depth.view);

            VkFramebufferCreateInfo fbufCreateInfo = Initializers.framebufferCreateInfo();

            fbufCreateInfo.renderPass      = offscreenPass.renderPass;
            fbufCreateInfo.attachmentCount = 2;
            fbufCreateInfo.pAttachments    = &attachments.First;
            fbufCreateInfo.width           = (uint)offscreenPass.width;
            fbufCreateInfo.height          = (uint)offscreenPass.height;
            fbufCreateInfo.layers          = 1;

            Util.CheckResult(vkCreateFramebuffer(device, &fbufCreateInfo, null, out offscreenPass.frameBuffer));

            // Fill a descriptor for later use in a descriptor set
            offscreenPass.descriptor.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
            offscreenPass.descriptor.imageView   = offscreenPass.color.view;
            offscreenPass.descriptor.sampler     = offscreenPass.sampler;
        }
Ejemplo n.º 20
0
        protected virtual void SetupRenderPass()
        {
            var attachments = new VkAttachmentDescription[2];

            // Color attachment
            attachments[0]                = new VkAttachmentDescription();
            attachments[0].format         = Swapchain.ColorFormat;
            attachments[0].samples        = VkSampleCountFlagBits._1;
            attachments[0].loadOp         = VkAttachmentLoadOp.Clear;
            attachments[0].storeOp        = VkAttachmentStoreOp.Store;
            attachments[0].stencilLoadOp  = VkAttachmentLoadOp.DontCare;
            attachments[0].stencilStoreOp = VkAttachmentStoreOp.DontCare;
            attachments[0].initialLayout  = VkImageLayout.Undefined;
            attachments[0].finalLayout    = VkImageLayout.PresentSrcKHR;
            // Depth attachment
            attachments[1]                = new VkAttachmentDescription();
            attachments[1].format         = DepthFormat;
            attachments[1].samples        = VkSampleCountFlagBits._1;
            attachments[1].loadOp         = VkAttachmentLoadOp.Clear;
            attachments[1].storeOp        = VkAttachmentStoreOp.Store;
            attachments[1].stencilLoadOp  = VkAttachmentLoadOp.DontCare;
            attachments[1].stencilStoreOp = VkAttachmentStoreOp.DontCare;
            attachments[1].initialLayout  = VkImageLayout.Undefined;
            attachments[1].finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal;

            VkAttachmentReference colorReference = new VkAttachmentReference();

            colorReference.attachment = 0;
            colorReference.layout     = VkImageLayout.ColorAttachmentOptimal;

            VkAttachmentReference depthReference = new VkAttachmentReference();

            depthReference.attachment = 1;
            depthReference.layout     = VkImageLayout.DepthStencilAttachmentOptimal;

            VkSubpassDescription subpassDescription = new VkSubpassDescription();

            subpassDescription.pipelineBindPoint = VkPipelineBindPoint.Graphics;
            subpassDescription.colorResolveAttachments.SetColorAttachments(colorReference);
            subpassDescription.pDepthStencilAttachment = &depthReference;

            // Subpass dependencies for layout transitions
            var dependencies = new VkSubpassDependency[2];

            dependencies[0].srcSubpass      = SubpassExternal;
            dependencies[0].dstSubpass      = 0;
            dependencies[0].srcStageMask    = VkPipelineStageFlagBits.BottomOfPipe;
            dependencies[0].dstStageMask    = VkPipelineStageFlagBits.ColorAttachmentOutput;
            dependencies[0].srcAccessMask   = VkAccessFlagBits.MemoryRead;
            dependencies[0].dstAccessMask   = (VkAccessFlagBits.ColorAttachmentRead | VkAccessFlagBits.ColorAttachmentWrite);
            dependencies[0].dependencyFlags = VkDependencyFlagBits.ByRegion;

            dependencies[1].srcSubpass      = 0;
            dependencies[1].dstSubpass      = SubpassExternal;
            dependencies[1].srcStageMask    = VkPipelineStageFlagBits.ColorAttachmentOutput;
            dependencies[1].dstStageMask    = VkPipelineStageFlagBits.BottomOfPipe;
            dependencies[1].srcAccessMask   = (VkAccessFlagBits.ColorAttachmentRead | VkAccessFlagBits.ColorAttachmentWrite);
            dependencies[1].dstAccessMask   = VkAccessFlagBits.MemoryRead;
            dependencies[1].dependencyFlags = VkDependencyFlagBits.ByRegion;

            VkRenderPassCreateInfo renderPassInfo = new VkRenderPassCreateInfo();

            renderPassInfo.sType        = RenderPassCreateInfo;
            renderPassInfo.attachments  = attachments;
            renderPassInfo.subpasses    = subpassDescription;
            renderPassInfo.dependencies = dependencies;
            VkRenderPass renderpass;

            vkCreateRenderPass(device, &renderPassInfo, null, &renderpass);
            this._renderPass = renderpass;
        }
Ejemplo n.º 21
0
        protected virtual void SetupRenderPass()
        {
            using (NativeList <VkAttachmentDescription> attachments = new NativeList <VkAttachmentDescription>())
            {
                attachments.Count = 2;
                // Color attachment
                attachments[0]                = new VkAttachmentDescription();
                attachments[0].format         = Swapchain.ColorFormat;
                attachments[0].samples        = VkSampleCountFlags.Count1;
                attachments[0].loadOp         = VkAttachmentLoadOp.Clear;
                attachments[0].storeOp        = VkAttachmentStoreOp.Store;
                attachments[0].stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                attachments[0].stencilStoreOp = VkAttachmentStoreOp.DontCare;
                attachments[0].initialLayout  = VkImageLayout.Undefined;
                attachments[0].finalLayout    = VkImageLayout.PresentSrcKHR;
                // Depth attachment
                attachments[1]                = new VkAttachmentDescription();
                attachments[1].format         = DepthFormat;
                attachments[1].samples        = VkSampleCountFlags.Count1;
                attachments[1].loadOp         = VkAttachmentLoadOp.Clear;
                attachments[1].storeOp        = VkAttachmentStoreOp.Store;
                attachments[1].stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                attachments[1].stencilStoreOp = VkAttachmentStoreOp.DontCare;
                attachments[1].initialLayout  = VkImageLayout.Undefined;
                attachments[1].finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal;

                VkAttachmentReference colorReference = new VkAttachmentReference();
                colorReference.attachment = 0;
                colorReference.layout     = VkImageLayout.ColorAttachmentOptimal;

                VkAttachmentReference depthReference = new VkAttachmentReference();
                depthReference.attachment = 1;
                depthReference.layout     = VkImageLayout.DepthStencilAttachmentOptimal;

                VkSubpassDescription subpassDescription = new VkSubpassDescription();
                subpassDescription.pipelineBindPoint       = VkPipelineBindPoint.Graphics;
                subpassDescription.colorAttachmentCount    = 1;
                subpassDescription.pColorAttachments       = &colorReference;
                subpassDescription.pDepthStencilAttachment = &depthReference;
                subpassDescription.inputAttachmentCount    = 0;
                subpassDescription.pInputAttachments       = null;
                subpassDescription.preserveAttachmentCount = 0;
                subpassDescription.pPreserveAttachments    = null;
                subpassDescription.pResolveAttachments     = null;

                // Subpass dependencies for layout transitions
                using (NativeList <VkSubpassDependency> dependencies = new NativeList <VkSubpassDependency>(2))
                {
                    dependencies.Count = 2;

                    dependencies[0].srcSubpass      = SubpassExternal;
                    dependencies[0].dstSubpass      = 0;
                    dependencies[0].srcStageMask    = VkPipelineStageFlags.BottomOfPipe;
                    dependencies[0].dstStageMask    = VkPipelineStageFlags.ColorAttachmentOutput;
                    dependencies[0].srcAccessMask   = VkAccessFlags.MemoryRead;
                    dependencies[0].dstAccessMask   = (VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite);
                    dependencies[0].dependencyFlags = VkDependencyFlags.ByRegion;

                    dependencies[1].srcSubpass      = 0;
                    dependencies[1].dstSubpass      = SubpassExternal;
                    dependencies[1].srcStageMask    = VkPipelineStageFlags.ColorAttachmentOutput;
                    dependencies[1].dstStageMask    = VkPipelineStageFlags.BottomOfPipe;
                    dependencies[1].srcAccessMask   = (VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite);
                    dependencies[1].dstAccessMask   = VkAccessFlags.MemoryRead;
                    dependencies[1].dependencyFlags = VkDependencyFlags.ByRegion;

                    VkRenderPassCreateInfo renderPassInfo = new VkRenderPassCreateInfo();
                    renderPassInfo.sType           = VkStructureType.RenderPassCreateInfo;
                    renderPassInfo.attachmentCount = attachments.Count;
                    renderPassInfo.pAttachments    = (VkAttachmentDescription *)attachments.Data.ToPointer();
                    renderPassInfo.subpassCount    = 1;
                    renderPassInfo.pSubpasses      = &subpassDescription;
                    renderPassInfo.dependencyCount = dependencies.Count;
                    renderPassInfo.pDependencies   = (VkSubpassDependency *)dependencies.Data;

                    Util.CheckResult(vkCreateRenderPass(device, &renderPassInfo, null, out _renderPass));
                }
            }
        }
Ejemplo n.º 22
0
 public abstract VkResult CreateRenderPass(VkRenderPassCreateInfo renderPassInfo, out VkRenderPass renderPass);
Ejemplo n.º 23
0
        public VkPipeline(VkGraphicsDevice gd, ref GraphicsPipelineDescription description)
            : base(ref description)
        {
            _gd = gd;
            IsComputePipeline = false;
            RefCount          = new ResourceRefCount(DisposeCore);

            VkGraphicsPipelineCreateInfo pipelineCI = VkGraphicsPipelineCreateInfo.New();

            // Blend State
            VkPipelineColorBlendStateCreateInfo blendStateCI = VkPipelineColorBlendStateCreateInfo.New();
            int attachmentsCount = description.BlendState.AttachmentStates.Length;
            VkPipelineColorBlendAttachmentState *attachmentsPtr
                = stackalloc VkPipelineColorBlendAttachmentState[attachmentsCount];

            for (int i = 0; i < attachmentsCount; i++)
            {
                BlendAttachmentDescription          vdDesc          = description.BlendState.AttachmentStates[i];
                VkPipelineColorBlendAttachmentState attachmentState = new VkPipelineColorBlendAttachmentState();
                attachmentState.srcColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceColorFactor);
                attachmentState.dstColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationColorFactor);
                attachmentState.colorBlendOp        = VkFormats.VdToVkBlendOp(vdDesc.ColorFunction);
                attachmentState.srcAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceAlphaFactor);
                attachmentState.dstAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationAlphaFactor);
                attachmentState.alphaBlendOp        = VkFormats.VdToVkBlendOp(vdDesc.AlphaFunction);
                attachmentState.blendEnable         = vdDesc.BlendEnabled;
                attachmentState.colorWriteMask      = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A;
                attachmentsPtr[i] = attachmentState;
            }

            blendStateCI.attachmentCount = (uint)attachmentsCount;
            blendStateCI.pAttachments    = attachmentsPtr;
            RgbaFloat blendFactor = description.BlendState.BlendFactor;

            blendStateCI.blendConstants_0 = blendFactor.R;
            blendStateCI.blendConstants_1 = blendFactor.G;
            blendStateCI.blendConstants_2 = blendFactor.B;
            blendStateCI.blendConstants_3 = blendFactor.A;

            pipelineCI.pColorBlendState = &blendStateCI;

            // Rasterizer State
            RasterizerStateDescription             rsDesc = description.RasterizerState;
            VkPipelineRasterizationStateCreateInfo rsCI   = VkPipelineRasterizationStateCreateInfo.New();

            rsCI.cullMode         = VkFormats.VdToVkCullMode(rsDesc.CullMode);
            rsCI.polygonMode      = VkFormats.VdToVkPolygonMode(rsDesc.FillMode);
            rsCI.depthClampEnable = !rsDesc.DepthClipEnabled;
            rsCI.frontFace        = rsDesc.FrontFace == FrontFace.Clockwise ? VkFrontFace.Clockwise : VkFrontFace.CounterClockwise;
            rsCI.lineWidth        = 1f;

            pipelineCI.pRasterizationState = &rsCI;

            ScissorTestEnabled = rsDesc.ScissorTestEnabled;

            // Dynamic State
            VkPipelineDynamicStateCreateInfo dynamicStateCI = VkPipelineDynamicStateCreateInfo.New();
            VkDynamicState *dynamicStates = stackalloc VkDynamicState[2];

            dynamicStates[0] = VkDynamicState.Viewport;
            dynamicStates[1] = VkDynamicState.Scissor;
            dynamicStateCI.dynamicStateCount = 2;
            dynamicStateCI.pDynamicStates    = dynamicStates;

            pipelineCI.pDynamicState = &dynamicStateCI;

            // Depth Stencil State
            DepthStencilStateDescription          vdDssDesc = description.DepthStencilState;
            VkPipelineDepthStencilStateCreateInfo dssCI     = VkPipelineDepthStencilStateCreateInfo.New();

            dssCI.depthWriteEnable  = vdDssDesc.DepthWriteEnabled;
            dssCI.depthTestEnable   = vdDssDesc.DepthTestEnabled;
            dssCI.depthCompareOp    = VkFormats.VdToVkCompareOp(vdDssDesc.DepthComparison);
            dssCI.stencilTestEnable = vdDssDesc.StencilTestEnabled;

            dssCI.front.failOp      = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.Fail);
            dssCI.front.passOp      = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.Pass);
            dssCI.front.depthFailOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.DepthFail);
            dssCI.front.compareOp   = VkFormats.VdToVkCompareOp(vdDssDesc.StencilFront.Comparison);
            dssCI.front.compareMask = vdDssDesc.StencilReadMask;
            dssCI.front.writeMask   = vdDssDesc.StencilWriteMask;
            dssCI.front.reference   = vdDssDesc.StencilReference;

            dssCI.back.failOp      = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.Fail);
            dssCI.back.passOp      = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.Pass);
            dssCI.back.depthFailOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.DepthFail);
            dssCI.back.compareOp   = VkFormats.VdToVkCompareOp(vdDssDesc.StencilBack.Comparison);
            dssCI.back.compareMask = vdDssDesc.StencilReadMask;
            dssCI.back.writeMask   = vdDssDesc.StencilWriteMask;
            dssCI.back.reference   = vdDssDesc.StencilReference;

            pipelineCI.pDepthStencilState = &dssCI;

            // Multisample
            VkPipelineMultisampleStateCreateInfo multisampleCI = VkPipelineMultisampleStateCreateInfo.New();
            VkSampleCountFlags vkSampleCount = VkFormats.VdToVkSampleCount(description.Outputs.SampleCount);

            multisampleCI.rasterizationSamples  = vkSampleCount;
            multisampleCI.alphaToCoverageEnable = description.BlendState.AlphaToCoverageEnabled;

            pipelineCI.pMultisampleState = &multisampleCI;

            // Input Assembly
            VkPipelineInputAssemblyStateCreateInfo inputAssemblyCI = VkPipelineInputAssemblyStateCreateInfo.New();

            inputAssemblyCI.topology = VkFormats.VdToVkPrimitiveTopology(description.PrimitiveTopology);

            pipelineCI.pInputAssemblyState = &inputAssemblyCI;

            // Vertex Input State
            VkPipelineVertexInputStateCreateInfo vertexInputCI = VkPipelineVertexInputStateCreateInfo.New();

            VertexLayoutDescription[] inputDescriptions = description.ShaderSet.VertexLayouts;
            uint bindingCount   = (uint)inputDescriptions.Length;
            uint attributeCount = 0;

            for (int i = 0; i < inputDescriptions.Length; i++)
            {
                attributeCount += (uint)inputDescriptions[i].Elements.Length;
            }
            VkVertexInputBindingDescription *  bindingDescs   = stackalloc VkVertexInputBindingDescription[(int)bindingCount];
            VkVertexInputAttributeDescription *attributeDescs = stackalloc VkVertexInputAttributeDescription[(int)attributeCount];

            int targetIndex    = 0;
            int targetLocation = 0;

            for (int binding = 0; binding < inputDescriptions.Length; binding++)
            {
                VertexLayoutDescription inputDesc = inputDescriptions[binding];
                bindingDescs[binding] = new VkVertexInputBindingDescription()
                {
                    binding   = (uint)binding,
                    inputRate = (inputDesc.InstanceStepRate != 0) ? VkVertexInputRate.Instance : VkVertexInputRate.Vertex,
                    stride    = inputDesc.Stride
                };

                uint currentOffset = 0;
                for (int location = 0; location < inputDesc.Elements.Length; location++)
                {
                    VertexElementDescription inputElement = inputDesc.Elements[location];

                    attributeDescs[targetIndex] = new VkVertexInputAttributeDescription()
                    {
                        format   = VkFormats.VdToVkVertexElementFormat(inputElement.Format),
                        binding  = (uint)binding,
                        location = (uint)(targetLocation + location),
                        offset   = inputElement.Offset != 0 ? inputElement.Offset : currentOffset
                    };

                    targetIndex   += 1;
                    currentOffset += FormatHelpers.GetSizeInBytes(inputElement.Format);
                }

                targetLocation += inputDesc.Elements.Length;
            }

            vertexInputCI.vertexBindingDescriptionCount   = bindingCount;
            vertexInputCI.pVertexBindingDescriptions      = bindingDescs;
            vertexInputCI.vertexAttributeDescriptionCount = attributeCount;
            vertexInputCI.pVertexAttributeDescriptions    = attributeDescs;

            pipelineCI.pVertexInputState = &vertexInputCI;

            // Shader Stage

            VkSpecializationInfo specializationInfo;

            SpecializationConstant[] specDescs = description.ShaderSet.Specializations;
            if (specDescs != null)
            {
                uint specDataSize = 0;
                foreach (SpecializationConstant spec in specDescs)
                {
                    specDataSize += VkFormats.GetSpecializationConstantSize(spec.Type);
                }
                byte *fullSpecData                   = stackalloc byte[(int)specDataSize];
                int   specializationCount            = specDescs.Length;
                VkSpecializationMapEntry *mapEntries = stackalloc VkSpecializationMapEntry[specializationCount];
                uint specOffset = 0;
                for (int i = 0; i < specializationCount; i++)
                {
                    ulong data     = specDescs[i].Data;
                    byte *srcData  = (byte *)&data;
                    uint  dataSize = VkFormats.GetSpecializationConstantSize(specDescs[i].Type);
                    Unsafe.CopyBlock(fullSpecData + specOffset, srcData, dataSize);
                    mapEntries[i].constantID = specDescs[i].ID;
                    mapEntries[i].offset     = specOffset;
                    mapEntries[i].size       = (UIntPtr)dataSize;
                    specOffset += dataSize;
                }
                specializationInfo.dataSize      = (UIntPtr)specDataSize;
                specializationInfo.pData         = fullSpecData;
                specializationInfo.mapEntryCount = (uint)specializationCount;
                specializationInfo.pMapEntries   = mapEntries;
            }

            Shader[] shaders = description.ShaderSet.Shaders;
            StackList <VkPipelineShaderStageCreateInfo> stages = new StackList <VkPipelineShaderStageCreateInfo>();

            foreach (Shader shader in shaders)
            {
                VkShader vkShader = Util.AssertSubtype <Shader, VkShader>(shader);
                VkPipelineShaderStageCreateInfo stageCI = VkPipelineShaderStageCreateInfo.New();
                stageCI.module = vkShader.ShaderModule;
                stageCI.stage  = VkFormats.VdToVkShaderStages(shader.Stage);
                // stageCI.pName = CommonStrings.main; // Meh
                stageCI.pName = new FixedUtf8String(shader.EntryPoint); // TODO: DONT ALLOCATE HERE
                stageCI.pSpecializationInfo = &specializationInfo;
                stages.Add(stageCI);
            }

            pipelineCI.stageCount = stages.Count;
            pipelineCI.pStages    = (VkPipelineShaderStageCreateInfo *)stages.Data;

            // ViewportState
            VkPipelineViewportStateCreateInfo viewportStateCI = VkPipelineViewportStateCreateInfo.New();

            viewportStateCI.viewportCount = 1;
            viewportStateCI.scissorCount  = 1;

            pipelineCI.pViewportState = &viewportStateCI;

            // Pipeline Layout
            ResourceLayout[]           resourceLayouts  = description.ResourceLayouts;
            VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New();

            pipelineLayoutCI.setLayoutCount = (uint)resourceLayouts.Length;
            VkDescriptorSetLayout *dsls = stackalloc VkDescriptorSetLayout[resourceLayouts.Length];

            for (int i = 0; i < resourceLayouts.Length; i++)
            {
                dsls[i] = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(resourceLayouts[i]).DescriptorSetLayout;
            }
            pipelineLayoutCI.pSetLayouts = dsls;

            vkCreatePipelineLayout(_gd.Device, ref pipelineLayoutCI, null, out _pipelineLayout);
            pipelineCI.layout = _pipelineLayout;

            // Create fake RenderPass for compatibility.

            VkRenderPassCreateInfo renderPassCI = VkRenderPassCreateInfo.New();
            OutputDescription      outputDesc   = description.Outputs;
            StackList <VkAttachmentDescription, Size512Bytes> attachments = new StackList <VkAttachmentDescription, Size512Bytes>();

            // TODO: A huge portion of this next part is duplicated in VkFramebuffer.cs.

            StackList <VkAttachmentDescription> colorAttachmentDescs = new StackList <VkAttachmentDescription>();
            StackList <VkAttachmentReference>   colorAttachmentRefs  = new StackList <VkAttachmentReference>();

            for (uint i = 0; i < outputDesc.ColorAttachments.Length; i++)
            {
                colorAttachmentDescs[i].format         = VkFormats.VdToVkPixelFormat(outputDesc.ColorAttachments[i].Format);
                colorAttachmentDescs[i].samples        = vkSampleCount;
                colorAttachmentDescs[i].loadOp         = VkAttachmentLoadOp.DontCare;
                colorAttachmentDescs[i].storeOp        = VkAttachmentStoreOp.Store;
                colorAttachmentDescs[i].stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                colorAttachmentDescs[i].stencilStoreOp = VkAttachmentStoreOp.DontCare;
                colorAttachmentDescs[i].initialLayout  = VkImageLayout.Undefined;
                colorAttachmentDescs[i].finalLayout    = VkImageLayout.ShaderReadOnlyOptimal;
                attachments.Add(colorAttachmentDescs[i]);

                colorAttachmentRefs[i].attachment = i;
                colorAttachmentRefs[i].layout     = VkImageLayout.ColorAttachmentOptimal;
            }

            VkAttachmentDescription depthAttachmentDesc = new VkAttachmentDescription();
            VkAttachmentReference   depthAttachmentRef  = new VkAttachmentReference();

            if (outputDesc.DepthAttachment != null)
            {
                PixelFormat depthFormat = outputDesc.DepthAttachment.Value.Format;
                bool        hasStencil  = FormatHelpers.IsStencilFormat(depthFormat);
                depthAttachmentDesc.format         = VkFormats.VdToVkPixelFormat(outputDesc.DepthAttachment.Value.Format, toDepthFormat: true);
                depthAttachmentDesc.samples        = vkSampleCount;
                depthAttachmentDesc.loadOp         = VkAttachmentLoadOp.DontCare;
                depthAttachmentDesc.storeOp        = VkAttachmentStoreOp.Store;
                depthAttachmentDesc.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                depthAttachmentDesc.stencilStoreOp = hasStencil ? VkAttachmentStoreOp.Store : VkAttachmentStoreOp.DontCare;
                depthAttachmentDesc.initialLayout  = VkImageLayout.Undefined;
                depthAttachmentDesc.finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal;

                depthAttachmentRef.attachment = (uint)outputDesc.ColorAttachments.Length;
                depthAttachmentRef.layout     = VkImageLayout.DepthStencilAttachmentOptimal;
            }

            VkSubpassDescription subpass = new VkSubpassDescription();

            subpass.pipelineBindPoint    = VkPipelineBindPoint.Graphics;
            subpass.colorAttachmentCount = (uint)outputDesc.ColorAttachments.Length;
            subpass.pColorAttachments    = (VkAttachmentReference *)colorAttachmentRefs.Data;
            for (int i = 0; i < colorAttachmentDescs.Count; i++)
            {
                attachments.Add(colorAttachmentDescs[i]);
            }

            if (outputDesc.DepthAttachment != null)
            {
                subpass.pDepthStencilAttachment = &depthAttachmentRef;
                attachments.Add(depthAttachmentDesc);
            }

            VkSubpassDependency subpassDependency = new VkSubpassDependency();

            subpassDependency.srcSubpass    = SubpassExternal;
            subpassDependency.srcStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite;

            renderPassCI.attachmentCount = attachments.Count;
            renderPassCI.pAttachments    = (VkAttachmentDescription *)attachments.Data;
            renderPassCI.subpassCount    = 1;
            renderPassCI.pSubpasses      = &subpass;
            renderPassCI.dependencyCount = 1;
            renderPassCI.pDependencies   = &subpassDependency;

            VkResult creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPass);

            CheckResult(creationResult);

            pipelineCI.renderPass = _renderPass;

            VkResult result = vkCreateGraphicsPipelines(_gd.Device, VkPipelineCache.Null, 1, ref pipelineCI, null, out _devicePipeline);

            CheckResult(result);

            ResourceSetCount    = (uint)description.ResourceLayouts.Length;
            DynamicOffsetsCount = 0;
            foreach (VkResourceLayout layout in description.ResourceLayouts)
            {
                DynamicOffsetsCount += layout.DynamicBufferCount;
            }
        }
Ejemplo n.º 24
0
        public void Build(int device_index)
        {
            if (!locked)
            {
                unsafe
                {
                    uint colorAttachmentCnt = (uint)(ColorAttachments == null ? 0 : ColorAttachments.Length);
                    uint depthAttachmentCnt = DepthAttachment != null ? 1u : 0u;

                    var colorAttachments = new VkAttachmentReference[colorAttachmentCnt];
                    for (int i = 0; i < colorAttachmentCnt; i++)
                    {
                        colorAttachments[i].attachment = (uint)i;
                        colorAttachments[i].layout     = (VkImageLayout)ColorAttachments[i].StartLayout;
                    }
                    var depthAttachment = new VkAttachmentReference()
                    {
                        attachment = colorAttachmentCnt,
                        layout     = DepthAttachment == null ? VkImageLayout.ImageLayoutUndefined : (VkImageLayout)DepthAttachment.StartLayout
                    };

                    var colorAttachments_ptr = colorAttachments.Pointer();
                    var depthAttachments_ptr = depthAttachment.Pointer();
                    var preserveAttachments  = stackalloc uint[] { colorAttachmentCnt };

                    var subpassDesc = new VkSubpassDescription()
                    {
                        pipelineBindPoint       = VkPipelineBindPoint.PipelineBindPointGraphics,
                        colorAttachmentCount    = colorAttachmentCnt,
                        pColorAttachments       = colorAttachments_ptr,
                        pDepthStencilAttachment = depthAttachmentCnt > 0 ? depthAttachments_ptr : IntPtr.Zero,
                        preserveAttachmentCount = 0u,
                        pPreserveAttachments    = preserveAttachments,
                    };
                    var subpassDesc_ptr = subpassDesc.Pointer();

                    var colorAttachmentDesc = new VkAttachmentDescription[colorAttachmentCnt + depthAttachmentCnt];
                    for (int i = 0; i < colorAttachmentCnt; i++)
                    {
                        colorAttachmentDesc[i].format         = (VkFormat)ColorAttachments[i].Format;
                        colorAttachmentDesc[i].samples        = VkSampleCountFlags.SampleCount1Bit;
                        colorAttachmentDesc[i].loadOp         = (VkAttachmentLoadOp)ColorAttachments[i].LoadOp;
                        colorAttachmentDesc[i].storeOp        = (VkAttachmentStoreOp)ColorAttachments[i].StoreOp;
                        colorAttachmentDesc[i].stencilLoadOp  = VkAttachmentLoadOp.AttachmentLoadOpDontCare;
                        colorAttachmentDesc[i].stencilStoreOp = VkAttachmentStoreOp.AttachmentStoreOpDontCare;
                        colorAttachmentDesc[i].initialLayout  = (VkImageLayout)ColorAttachments[i].InitialLayout;
                        colorAttachmentDesc[i].finalLayout    = (VkImageLayout)ColorAttachments[i].FinalLayout;
                    }
                    if (depthAttachmentCnt > 0)
                    {
                        colorAttachmentDesc[colorAttachmentCnt].format         = (VkFormat)DepthAttachment.Format;
                        colorAttachmentDesc[colorAttachmentCnt].samples        = VkSampleCountFlags.SampleCount1Bit;
                        colorAttachmentDesc[colorAttachmentCnt].loadOp         = (VkAttachmentLoadOp)DepthAttachment.LoadOp;
                        colorAttachmentDesc[colorAttachmentCnt].storeOp        = (VkAttachmentStoreOp)DepthAttachment.StoreOp;
                        colorAttachmentDesc[colorAttachmentCnt].stencilLoadOp  = VkAttachmentLoadOp.AttachmentLoadOpDontCare;
                        colorAttachmentDesc[colorAttachmentCnt].stencilStoreOp = VkAttachmentStoreOp.AttachmentStoreOpDontCare;
                        colorAttachmentDesc[colorAttachmentCnt].initialLayout  = (VkImageLayout)DepthAttachment.InitialLayout;
                        colorAttachmentDesc[colorAttachmentCnt].finalLayout    = (VkImageLayout)DepthAttachment.FinalLayout;
                    }
                    var colorAttachmentDesc_ptr = colorAttachmentDesc.Pointer();

                    var subpassDependency = new VkSubpassDependency()
                    {
                        srcSubpass    = VkSubpassExternal,
                        dstSubpass    = 0,
                        srcStageMask  = VkPipelineStageFlags.PipelineStageAllCommandsBit,
                        srcAccessMask = 0,
                        dstStageMask  = VkPipelineStageFlags.PipelineStageVertexShaderBit,
                        dstAccessMask = VkAccessFlags.AccessMemoryReadBit,
                    };
                    var subpassDependency_ptr = subpassDependency.Pointer();

                    var renderPassInfo = new VkRenderPassCreateInfo()
                    {
                        sType           = VkStructureType.StructureTypeRenderPassCreateInfo,
                        attachmentCount = colorAttachmentCnt + depthAttachmentCnt,
                        pAttachments    = colorAttachmentDesc_ptr,
                        subpassCount    = 1,
                        pSubpasses      = subpassDesc_ptr,
                        dependencyCount = 1,
                        pDependencies   = subpassDependency_ptr
                    };
                    IntPtr renderPass_l = IntPtr.Zero;
                    if (vkCreateRenderPass(GraphicsDevice.GetDeviceInfo(device_index).Device, renderPassInfo.Pointer(), null, &renderPass_l) != VkResult.Success)
                    {
                        throw new Exception("Failed to create RenderPass.");
                    }
                    hndl  = renderPass_l;
                    devID = device_index;

                    if (GraphicsDevice.EnableValidation)
                    {
                        var objName = new VkDebugUtilsObjectNameInfoEXT()
                        {
                            sType        = VkStructureType.StructureTypeDebugUtilsObjectNameInfoExt,
                            pObjectName  = Name,
                            objectType   = VkObjectType.ObjectTypeRenderPass,
                            objectHandle = (ulong)hndl
                        };
                        GraphicsDevice.SetDebugUtilsObjectNameEXT(GraphicsDevice.GetDeviceInfo(devID).Device, objName.Pointer());
                    }
                }
                locked = true;
            }
            else
            {
                throw new Exception("RenderPass is locked.");
            }
        }