Esempio n. 1
0
        // Sets up the command buffer that renders the scene to the offscreen frame buffer
        void buildOffscreenCommandBuffer()
        {
            if (offscreenPass.commandBuffer == NullHandle)
            {
                offscreenPass.commandBuffer = createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, false);
            }
            if (offscreenPass.semaphore == NullHandle)
            {
                VkSemaphoreCreateInfo semaphoreCreateInfo = Initializers.semaphoreCreateInfo();
                Util.CheckResult(vkCreateSemaphore(device, &semaphoreCreateInfo, null, out offscreenPass.semaphore));
            }

            VkCommandBufferBeginInfo cmdBufInfo = Initializers.commandBufferBeginInfo();

            FixedArray2 <VkClearValue> clearValues = new FixedArray2 <VkClearValue>();

            clearValues.First.color = new VkClearColorValue {
                float32_0 = 0.0f, float32_1 = 0.0f, float32_2 = 0.0f, float32_3 = 0.0f
            };
            clearValues.Second.depthStencil = new VkClearDepthStencilValue {
                depth = 1.0f, stencil = 0
            };

            VkRenderPassBeginInfo renderPassBeginInfo = Initializers.renderPassBeginInfo();

            renderPassBeginInfo.renderPass               = offscreenPass.renderPass;
            renderPassBeginInfo.framebuffer              = offscreenPass.frameBuffer;
            renderPassBeginInfo.renderArea.extent.width  = offscreenPass.width;
            renderPassBeginInfo.renderArea.extent.height = offscreenPass.height;
            renderPassBeginInfo.clearValueCount          = 2;
            renderPassBeginInfo.pClearValues             = &clearValues.First;

            Util.CheckResult(vkBeginCommandBuffer(offscreenPass.commandBuffer, &cmdBufInfo));

            VkViewport viewport = Initializers.viewport((float)offscreenPass.width, (float)offscreenPass.height, 0.0f, 1.0f);

            vkCmdSetViewport(offscreenPass.commandBuffer, 0, 1, &viewport);

            VkRect2D scissor = Initializers.rect2D(offscreenPass.width, offscreenPass.height, 0, 0);

            vkCmdSetScissor(offscreenPass.commandBuffer, 0, 1, &scissor);

            vkCmdBeginRenderPass(offscreenPass.commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);

            vkCmdBindDescriptorSets(offscreenPass.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts_scene, 0, 1, ref descriptorSets_scene, 0, null);
            vkCmdBindPipeline(offscreenPass.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines_colorPass);

            ulong offsets = 0;

            vkCmdBindVertexBuffers(offscreenPass.commandBuffer, VERTEX_BUFFER_BIND_ID, 1, ref models_example.vertices.buffer, &offsets);
            vkCmdBindIndexBuffer(offscreenPass.commandBuffer, models_example.indices.buffer, 0, VK_INDEX_TYPE_UINT32);
            vkCmdDrawIndexed(offscreenPass.commandBuffer, models_example.indexCount, 1, 0, 0, 0);

            vkCmdEndRenderPass(offscreenPass.commandBuffer);

            Util.CheckResult(vkEndCommandBuffer(offscreenPass.commandBuffer));
        }
Esempio n. 2
0
        public void InitVulkan()
        {
            VkResult err;

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

            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);
            this.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;
        }