示例#1
0
文件: triangle.py 项目: geehalel/pyvk
 def draw(self):
     nextBuffer = self.swapChain.acquireNextImage(
         self.semaphores['presentComplete'], self.currentBuffer)
     self.currentBuffer = nextBuffer
     #print(nextBuffer)
     # Use a fence to wait until the command buffer has finished execution before using it again
     vk.vkWaitForFences(self.device, 1,
                        [self.waitFences[self.currentBuffer]], vk.VK_TRUE,
                        vk.UINT64_MAX)
     vk.vkResetFences(self.device, 1, [self.waitFences[self.currentBuffer]])
     # Pipeline stage at which the queue submission will wait (via pWaitSemaphores)
     waitStageMask = vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
     # The submit info structure specifices a command buffer queue submission batch
     submitInfo = vk.VkSubmitInfo(
         sType=vk.VK_STRUCTURE_TYPE_SUBMIT_INFO,
         pWaitDstStageMask=[waitStageMask],
         pWaitSemaphores=[self.semaphores['presentComplete']],
         waitSemaphoreCount=1,
         signalSemaphoreCount=1,
         pSignalSemaphores=[self.semaphores['renderComplete']],
         pCommandBuffers=[self.drawCmdBuffers[self.currentBuffer]],
         commandBufferCount=1)
     # Submit to the graphics queue passing a wait fence
     vk.vkQueueSubmit(self.queue, 1, submitInfo,
                      self.waitFences[self.currentBuffer])
     # Present the current buffer to the swap chain
     # Pass the semaphore signaled by the command buffer submission from the submit info as the wait semaphore for swap chain presentation
     # This ensures that the image is not presented to the windowing system until all commands have been submitted
     try:
         self.swapChain.queuePresent(self.queue, self.currentBuffer,
                                     self.semaphores['renderComplete'])
     except vk.VkErrorOutOfDateKhr:
         self.windowResize()
示例#2
0
    def swap(self, semaphores=None):
        """Display final image on screen.

        This function makes all the rendering work. To proceed, it copies the
        `final_image` into the current swapchain image previously acquired.
        You can pass custom semaphores (and you should) to synchronize the
        command.

        Args:
            semaphore (list[Semaphore]): semaphores to wait on

        **Note: `final_image` layout is handled by `VulkContext`. You must
                 let it to COLOR_ATTACHMENT_OPTIMAL**
        """
        # Acquire image
        try:
            index = self.pfn['vkAcquireNextImageKHR'](
                self.device, self.swapchain, vk.UINT64_MAX,
                self._semaphore_available.semaphore, None)
        except vk.VkErrorOutOfDateKhr:
            logger.warning("Swapchain out of date, reloading...")
            self.reload_swapchain()
            return

        wait_semaphores = [self._semaphore_available]
        if semaphores:
            wait_semaphores.extend([s for s in semaphores if s])

        wait_masks = [vc.PipelineStage.COLOR_ATTACHMENT_OUTPUT]
        wait_masks *= len(wait_semaphores)

        copied_semaphores = [self._semaphore_copied.semaphore]

        # Transfer final image to swapchain image
        submit = vk.VkSubmitInfo(
            sType=vk.VK_STRUCTURE_TYPE_SUBMIT_INFO,
            waitSemaphoreCount=len(wait_semaphores),
            pWaitSemaphores=[s.semaphore for s in wait_semaphores],
            pWaitDstStageMask=wait_masks,
            commandBufferCount=1,
            pCommandBuffers=[self.commandbuffers[index].commandbuffer],
            signalSemaphoreCount=len(copied_semaphores),
            pSignalSemaphores=copied_semaphores)
        vk.vkQueueSubmit(self.graphic_queue, 1, [submit], None)

        # Present swapchain image on screen
        present = vk.VkPresentInfoKHR(
            sType=vk.VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
            waitSemaphoreCount=len(copied_semaphores),
            pWaitSemaphores=copied_semaphores,
            swapchainCount=1,
            pSwapchains=[self.swapchain],
            pImageIndices=[index],
            pResults=None)
        self.pfn['vkQueuePresentKHR'](self.present_queue, present)

        vk.vkDeviceWaitIdle(self.device)
示例#3
0
    def submit(self, command_buffer: CommandBuffer,
               render_semaphore: VulkanSemaphore,
               image_semaphore: VulkanSemaphore):

        submit = vulkan.VkSubmitInfo(
            pWaitSemaphores=[image_semaphore.vk_semaphore],
            pWaitDstStageMask=[
                vulkan.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
            ],
            pCommandBuffers=[command_buffer.vk_command_buffer],
            pSignalSemaphores=[render_semaphore.vk_semaphore])

        vulkan.vkQueueSubmit(self.vk_queue, 1, submit, None)
示例#4
0
 def draw(self):
     super().prepareFrame()
     # self.submitInfo.commandBufferCount = 1
     # TODO try to avoid creating submitInfo at each frame
     # need to get CData pointer on drawCmdBuffers[*]
     # self.submitInfo.pCommandBuffers[0] = self.drawCmdBuffers[self.currentBuffer]
     # vk.vkQueueSubmit(self.queue, 1, self.submit_list, vk.VK_NULL_HANDLE)
     submitInfo = vk.VkSubmitInfo(
         sType=vk.VK_STRUCTURE_TYPE_SUBMIT_INFO,
         pWaitDstStageMask=[
             vk.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
         ],
         pWaitSemaphores=[self.semaphores['presentComplete']],
         waitSemaphoreCount=1,
         signalSemaphoreCount=1,
         pSignalSemaphores=[self.semaphores['renderComplete']],
         pCommandBuffers=[self.drawCmdBuffers[self.currentBuffer]],
         commandBufferCount=1)
     vk.vkQueueSubmit(self.queue, 1, submitInfo, vk.VK_NULL_HANDLE)
     super().submitFrame()
示例#5
0
文件: triangle.py 项目: geehalel/pyvk
    def flushCommandBuffer(self, commandBuffer):
        """
End the command buffer and submit it to the queue
Uses a fence to ensure command buffer has finished executing before deleting it
        """
        assert (commandBuffer != vk.VK_NULL_HANDLE)
        vk.vkEndCommandBuffer(commandBuffer)

        submitInfo = vk.VkSubmitInfo(sType=vk.VK_STRUCTURE_TYPE_SUBMIT_INFO,
                                     commandBufferCount=1,
                                     pCommandBuffers=[commandBuffer])
        # Create fence to ensure that the command buffer has finished executing
        fenceCreateInfo = vk.VkFenceCreateInfo(
            sType=vk.VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, flags=0)
        fence = vk.vkCreateFence(self.device, fenceCreateInfo, None)
        # Submit to the queue
        vk.vkQueueSubmit(self.queue, 1, [submitInfo], fence)
        # Wait for the fence to signal that command buffer has finished executing
        vk.vkWaitForFences(self.device, 1, [fence], vk.VK_TRUE,
                           vks.vulkanglobals.DEFAULT_FENCE_TIMEOUT)

        vk.vkDestroyFence(self.device, fence, None)
        vk.vkFreeCommandBuffers(self.device, self.cmdPool, 1, [commandBuffer])
示例#6
0
    def loadMeshes(self, copyCmd):
        # allocate numpy arrays
        vertexCount = 0
        indexCount = 0
        for aMesh in self.aScene.meshes:
            vertexCount += len(aMesh.vertices)
            indexCount += len(aMesh.faces) * 3
        vertices = np.empty((vertexCount, ), dtype=self.vertexShape)
        indices = np.empty((indexCount, ), dtype=np.uint32)
        indexBase = 0
        vertexCount = 0
        indexCount = 0
        for aMesh in self.aScene.meshes:
            print("Mesh \"" + aMesh.name + "\"")
            print("  Material: \"" +
                  self.materials[aMesh.materialindex]["name"] + "\"")
            print("  Faces: " + str(len(aMesh.faces)))
            scenepart = {
                'material': self.materials[aMesh.materialindex],
                'indexBase': indexBase,
                'indexCount': len(aMesh.faces) * 3
            }
            self.meshes.append(scenepart)
            # Vertices
            hasUV = len(aMesh.texturecoords) > 0
            hasColor = len(aMesh.colors) > 0
            hasNormals = len(aMesh.normals) > 0
            print("  hasUV", hasUV, "hasColor", hasColor, "hasNormals",
                  hasNormals)
            for v in range(len(aMesh.vertices)):
                vertices[vertexCount]['pos'] = aMesh.vertices[v]
                vertices[vertexCount]['pos'] = -vertices[vertexCount]['pos']
                vertices[vertexCount]['uv'] = aMesh.texturecoords[0][
                    v][:2] if hasUV else [0.0, 0.0]
                vertices[vertexCount]['normal'] = aMesh.normals[
                    v] if hasNormals else [0.0, 0.0, 0.0]
                vertices[vertexCount][
                    'normal'] = -vertices[vertexCount]['normal']
                vertices[vertexCount]['color'] = aMesh.colors[
                    v] if hasColor else [1.0, 1.0, 1.0]
                vertexCount += 1
            # Indices
            for f in range(len(aMesh.faces)):
                for j in range(3):
                    indices[indexCount] = aMesh.faces[f][j]
                    indexCount += 1
            indexBase += len(aMesh.faces) * 3
        # Create buffers
        # For better performance we only create one index and vertex buffer to keep number of memory allocations down
        vertexDataSize = vertices.size * vertices.itemsize
        indexDataSize = indices.size * indices.itemsize
        # Vertex buffer
        #  Staging buffer
        vertexStaging = self.vulkanDevice.createvksBuffer(
            vk.VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
            vk.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
            | vk.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexDataSize,
            vertices)
        # Target
        self.vertexBuffer = self.vulkanDevice.createvksBuffer(
            vk.VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
            | vk.VK_BUFFER_USAGE_TRANSFER_DST_BIT,
            vk.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexDataSize)
        # Index buffer
        #  Staging buffer
        indexStaging = self.vulkanDevice.createvksBuffer(
            vk.VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
            vk.VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
            | vk.VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexDataSize, indices)
        # Target
        self.indexBuffer = self.vulkanDevice.createvksBuffer(
            vk.VK_BUFFER_USAGE_INDEX_BUFFER_BIT
            | vk.VK_BUFFER_USAGE_TRANSFER_DST_BIT,
            vk.VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexDataSize)
        # Copy
        cmdBufInfo = vk.VkCommandBufferBeginInfo(
            sType=vk.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, )
        vk.vkBeginCommandBuffer(copyCmd, cmdBufInfo)
        copyRegion = vk.VkBufferCopy(size=vertexDataSize)
        vk.vkCmdCopyBuffer(copyCmd, vertexStaging.buffer,
                           self.vertexBuffer.buffer, 1, copyRegion)
        copyRegion = vk.VkBufferCopy(size=indexDataSize)
        vk.vkCmdCopyBuffer(copyCmd, indexStaging.buffer,
                           self.indexBuffer.buffer, 1, copyRegion)
        vk.vkEndCommandBuffer(copyCmd)
        submitInfo = vk.VkSubmitInfo(sType=vk.VK_STRUCTURE_TYPE_SUBMIT_INFO,
                                     pCommandBuffers=[copyCmd],
                                     commandBufferCount=1)
        vk.vkQueueSubmit(self.queue, 1, submitInfo, vk.VK_NULL_HANDLE)
        vk.vkQueueWaitIdle(self.queue)

        vertexStaging.destroy()
        indexStaging.destroy()