Example #1
0
        void preparePipelines()
        {
            VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
                Initializers.pipelineInputAssemblyStateCreateInfo(
                    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
                    0,
                    VK_FALSE);

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

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

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

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

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

            VkPipelineMultisampleStateCreateInfo multisampleState =
                Initializers.pipelineMultisampleStateCreateInfo(
                    VkSampleCountFlags.Count1,
                    0);

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

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

            // Solid rendering pipeline
            // Load shaders
            FixedArray2<VkPipelineShaderStageCreateInfo> shaderStages = new FixedArray2<VkPipelineShaderStageCreateInfo>(
                loadShader(getAssetPath() + "shaders/offscreen/quad.vert.spv", VK_SHADER_STAGE_VERTEX_BIT),
                loadShader(getAssetPath() + "shaders/offscreen/quad.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT));

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

            var vis = vertices_inputState;
            pipelineCreateInfo.pVertexInputState = &vis;
            pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
            pipelineCreateInfo.pRasterizationState = &rasterizationState;
            pipelineCreateInfo.pColorBlendState = &colorBlendState;
            pipelineCreateInfo.pMultisampleState = &multisampleState;
            pipelineCreateInfo.pViewportState = &viewportState;
            pipelineCreateInfo.pDepthStencilState = &depthStencilState;
            pipelineCreateInfo.pDynamicState = &dynamicState;
            pipelineCreateInfo.stageCount = shaderStages.Count;
            pipelineCreateInfo.pStages = &shaderStages.First;

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

            // Mirror
            shaderStages.First = loadShader(getAssetPath() + "shaders/offscreen/mirror.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
            shaderStages.Second = loadShader(getAssetPath() + "shaders/offscreen/mirror.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
            rasterizationState.cullMode = VK_CULL_MODE_NONE;
            Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_mirror));

            // Flip culling
            rasterizationState.cullMode = VK_CULL_MODE_BACK_BIT;

            // Phong shading pipelines
            pipelineCreateInfo.layout = pipelineLayouts_shaded;
            // Scene
            shaderStages.First = loadShader(getAssetPath() + "shaders/offscreen/phong.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
            shaderStages.Second = loadShader(getAssetPath() + "shaders/offscreen/phong.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
            Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_shaded));
            // Offscreen
            // Flip culling
            rasterizationState.cullMode = VK_CULL_MODE_FRONT_BIT;
            pipelineCreateInfo.renderPass = offscreenPass.renderPass;
            Util.CheckResult(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, null, out pipelines_shadedOffscreen));

        }
Example #2
0
        protected override void buildCommandBuffers()
        {
            VkCommandBufferBeginInfo cmdBufInfo = Initializers.commandBufferBeginInfo();

            FixedArray2<VkClearValue> clearValues = new FixedArray2<VkClearValue>();
            clearValues.First.color = defaultClearColor;
            clearValues.Second.depthStencil = new VkClearDepthStencilValue { depth = 1.0f, stencil = 0 };

            VkRenderPassBeginInfo renderPassBeginInfo = Initializers.renderPassBeginInfo();
            renderPassBeginInfo.renderPass = renderPass;
            renderPassBeginInfo.renderArea.offset.x = 0;
            renderPassBeginInfo.renderArea.offset.y = 0;
            renderPassBeginInfo.renderArea.extent.width = width;
            renderPassBeginInfo.renderArea.extent.height = height;
            renderPassBeginInfo.clearValueCount = 2;
            renderPassBeginInfo.pClearValues = &clearValues.First;

            for (int i = 0; i < drawCmdBuffers.Count; ++i)
            {
                // Set target frame buffer
                renderPassBeginInfo.framebuffer = frameBuffers[i];

                Util.CheckResult(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo));

                vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);

                VkViewport viewport = Initializers.viewport((float)width, (float)height, 0.0f, 1.0f);
                vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);

                VkRect2D scissor = Initializers.rect2D(width, height, 0, 0);
                vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);

                ulong offsets = 0;

                if (debugDisplay)
                {
                    vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts_textured, 0, 1, ref descriptorSets_debugQuad, 0, null);
                    vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines_debug);
                    vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, ref models_quad.vertices.buffer, &offsets);
                    vkCmdBindIndexBuffer(drawCmdBuffers[i], models_quad.indices.buffer, 0, VK_INDEX_TYPE_UINT32);
                    vkCmdDrawIndexed(drawCmdBuffers[i], models_quad.indexCount, 1, 0, 0, 0);
                }

                // Scene
                vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines_debug);

                // Reflection plane
                vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts_textured, 0, 1, ref descriptorSets_mirror, 0, null);
                vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines_mirror);

                vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, ref models_plane.vertices.buffer, &offsets);
                vkCmdBindIndexBuffer(drawCmdBuffers[i], models_plane.indices.buffer, 0, VK_INDEX_TYPE_UINT32);
                vkCmdDrawIndexed(drawCmdBuffers[i], models_plane.indexCount, 1, 0, 0, 0);

                // Model
                vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts_shaded, 0, 1, ref descriptorSets_model, 0, null);
                vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines_shaded);

                vkCmdBindVertexBuffers(drawCmdBuffers[i], VERTEX_BUFFER_BIND_ID, 1, ref models_example.vertices.buffer, &offsets);
                vkCmdBindIndexBuffer(drawCmdBuffers[i], models_example.indices.buffer, 0, VK_INDEX_TYPE_UINT32);
                vkCmdDrawIndexed(drawCmdBuffers[i], models_example.indexCount, 1, 0, 0, 0);

                vkCmdEndRenderPass(drawCmdBuffers[i]);

                Util.CheckResult(vkEndCommandBuffer(drawCmdBuffers[i]));
            }
        }
Example #3
0
        void setupDescriptorSet()
        {
            var dsl = descriptorSetLayouts_textured;
            // Mirror plane descriptor set
            VkDescriptorSetAllocateInfo allocInfo =
                Initializers.descriptorSetAllocateInfo(
                    descriptorPool,
                    &dsl,
                    1);

            Util.CheckResult(vkAllocateDescriptorSets(device, &allocInfo, out descriptorSets_mirror));

            var descriptor0 = uniformBuffers_vsMirror.descriptor;
            var descriptor1 = offscreenPass.descriptor;
            var descriptor2 = textures_colorMap.descriptor;
            FixedArray3<VkWriteDescriptorSet> writeDescriptorSets = new FixedArray3<VkWriteDescriptorSet>(
                // Binding 0 : Vertex shader uniform buffer
                Initializers.writeDescriptorSet(
                    descriptorSets_mirror,
                    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
                    0,
                    &descriptor0),
                // Binding 1 : Fragment shader texture sampler
                Initializers.writeDescriptorSet(
                    descriptorSets_mirror,
                    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
                    1,
                    &descriptor1),
                // Binding 2 : Fragment shader texture sampler
                Initializers.writeDescriptorSet(
                    descriptorSets_mirror,
                    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
                    2,
                    &descriptor2));

            vkUpdateDescriptorSets(device, writeDescriptorSets.Count, &writeDescriptorSets.First, 0, null);

            // Debug quad
            Util.CheckResult(vkAllocateDescriptorSets(device, &allocInfo, out descriptorSets_debugQuad));

            var descriptor3 = uniformBuffers_vsDebugQuad.descriptor;
            var descriptor4 = offscreenPass.descriptor;
            FixedArray2<VkWriteDescriptorSet> debugQuadWriteDescriptorSets = new FixedArray2<VkWriteDescriptorSet>(
                // Binding 0 : Vertex shader uniform buffer
                Initializers.writeDescriptorSet(
                    descriptorSets_debugQuad,
                    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
                    0,
                    &descriptor3),
                // Binding 1 : Fragment shader texture sampler
                Initializers.writeDescriptorSet(
                    descriptorSets_debugQuad,
                    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
                    1,
                    &descriptor4));

            vkUpdateDescriptorSets(device, debugQuadWriteDescriptorSets.Count, &debugQuadWriteDescriptorSets.First, 0, null);

            var dsls_shaded = descriptorSetLayouts_shaded;
            // Shaded descriptor sets
            allocInfo.pSetLayouts = &dsls_shaded;

            // Model
            // No texture
            Util.CheckResult(vkAllocateDescriptorSets(device, &allocInfo, out descriptorSets_model));

            var descriptor5 = uniformBuffers_vsShared.descriptor;
            VkWriteDescriptorSet modelWriteDescriptorSets =
                // Binding 0 : Vertex shader uniform buffer
                Initializers.writeDescriptorSet(
                    descriptorSets_model,
                    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
                    0,
                    &descriptor5);
            vkUpdateDescriptorSets(device, 1, &modelWriteDescriptorSets, 0, null);

            // Offscreen
            Util.CheckResult(vkAllocateDescriptorSets(device, &allocInfo, out descriptorSets_offscreen));

            var descriptor6 = uniformBuffers_vsOffScreen.descriptor;
            VkWriteDescriptorSet offScreenWriteDescriptorSets =
            // Binding 0 : Vertex shader uniform buffer
            Initializers.writeDescriptorSet(
                descriptorSets_offscreen,
                VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
                0,
                &descriptor6);

            vkUpdateDescriptorSets(device, 1, &offScreenWriteDescriptorSets, 0, null);
        }
Example #4
0
        // Setup the offscreen framebuffer for rendering the mirrored scene
        // The color attachment of this framebuffer will then be used to sample from 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 = VkSampleCountFlags.Count1;
            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(VkImageAspectFlags.Color);
            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 = VkSampleCountFlags.Count1;
            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 = VkSampleCountFlags.Count1;
            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;
        }
Example #5
0
        private void CreatePipelineCache()
        {
            VkPipelineCacheCreateInfo pipelineCacheCreateInfo = VkPipelineCacheCreateInfo.New();

            Util.CheckResult(vkCreatePipelineCache(Device, ref pipelineCacheCreateInfo, null, out _pipelineCache));
        }
Example #6
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._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.PresentSrc;
                // Depth attachment
                attachments[1]                = new VkAttachmentDescription();
                attachments[1].format         = DepthFormat;
                attachments[1].samples        = VkSampleCountFlags._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.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));
                }
            }
        }
Example #7
0
 protected void prepareFrame()
 {
     // Acquire the next image from the swap chaing
     Util.CheckResult(Swapchain.AcquireNextImage(Semaphores[0].PresentComplete, ref currentBuffer));
 }
Example #8
0
        public void InitVulkan()
        {
            VkResult err;

            err = CreateInstance(true);
            if (err != VkResult.Success)
            {
                throw new InvalidOperationException("Could not create Vulkan instance.");
            }

            if (Settings.Validation)
            {
            }

            // Physical Device
            uint gpuCount = 0;

            Util.CheckResult(vkEnumeratePhysicalDevices(Instance, &gpuCount, null));
            Debug.Assert(gpuCount > 0);
            // Enumerate devices
            IntPtr *physicalDevices = stackalloc IntPtr[(int)gpuCount];

            err = vkEnumeratePhysicalDevices(Instance, &gpuCount, (VkPhysicalDevice *)physicalDevices);
            if (err != VkResult.Success)
            {
                throw new InvalidOperationException("Could not enumerate physical devices.");
            }

            // GPU selection

            // Select physical Device to be used for the Vulkan example
            // Defaults to the first Device unless specified by command line

            uint selectedDevice = 0;

            // TODO: Implement arg parsing, etc.

            PhysicalDevice = ((VkPhysicalDevice *)physicalDevices)[selectedDevice];

            // Store properties (including limits) and features of the phyiscal Device
            // So examples can check against them and see if a feature is actually supported
            VkPhysicalDeviceProperties deviceProperties;

            vkGetPhysicalDeviceProperties(PhysicalDevice, &deviceProperties);
            DeviceProperties = deviceProperties;

            VkPhysicalDeviceFeatures deviceFeatures;

            vkGetPhysicalDeviceFeatures(PhysicalDevice, &deviceFeatures);
            DeviceFeatures = deviceFeatures;

            // Gather physical Device memory properties
            VkPhysicalDeviceMemoryProperties deviceMemoryProperties;

            vkGetPhysicalDeviceMemoryProperties(PhysicalDevice, &deviceMemoryProperties);
            DeviceMemoryProperties = deviceMemoryProperties;

            // Derived examples can override this to set actual features (based on above readings) to enable for logical device creation
            getEnabledFeatures();

            // Vulkan Device creation
            // This is handled by a separate class that gets a logical Device representation
            // and encapsulates functions related to a Device
            VulkanDevice = new vksVulkanDevice(PhysicalDevice);
            VkResult res = VulkanDevice.CreateLogicalDevice(EnabledFeatures, EnabledExtensions);

            if (res != VkResult.Success)
            {
                throw new InvalidOperationException("Could not create Vulkan Device.");
            }
            Device = VulkanDevice.LogicalDevice;

            // Get a graphics queue from the Device
            VkQueue queue;

            vkGetDeviceQueue(Device, VulkanDevice.QFIndices.Graphics, 0, &queue);
            Queue = queue;

            // Find a suitable depth format
            VkFormat depthFormat;
            uint     validDepthFormat = Tools.getSupportedDepthFormat(PhysicalDevice, &depthFormat);

            Debug.Assert(validDepthFormat == True);
            DepthFormat = depthFormat;

            Swapchain.Connect(Instance, PhysicalDevice, Device);

            // Create synchronization objects
            VkSemaphoreCreateInfo semaphoreCreateInfo = Initializers.SemaphoreCreateInfo();

            // Create a semaphore used to synchronize image presentation
            // Ensures that the image is displayed before we start submitting new commands to the queu
            Util.CheckResult(vkCreateSemaphore(Device, &semaphoreCreateInfo, null, &GetSemaphoresPtr()->PresentComplete));
            // Create a semaphore used to synchronize command submission
            // Ensures that the image is not presented until all commands have been sumbitted and executed
            Util.CheckResult(vkCreateSemaphore(Device, &semaphoreCreateInfo, null, &GetSemaphoresPtr()->RenderComplete));
            // Create a semaphore used to synchronize command submission
            // Ensures that the image is not presented until all commands for the text overlay have been sumbitted and executed
            // Will be inserted after the render complete semaphore if the text overlay is enabled
            Util.CheckResult(vkCreateSemaphore(Device, &semaphoreCreateInfo, null, &GetSemaphoresPtr()->TextOverlayComplete));

            // Set up submit info structure
            // Semaphores will stay the same during application lifetime
            // Command buffer submission info is set by each example
            SubmitInfo = Initializers.SubmitInfo();
            SubmitInfo.pWaitDstStageMask    = (VkPipelineStageFlags *)submitPipelineStages.Data;
            SubmitInfo.waitSemaphoreCount   = 1;
            SubmitInfo.pWaitSemaphores      = &GetSemaphoresPtr()->PresentComplete;
            SubmitInfo.signalSemaphoreCount = 1;
            SubmitInfo.pSignalSemaphores    = &GetSemaphoresPtr()->RenderComplete;
        }