Beispiel #1
0
    def begin(self):

        begin = vulkan.VkCommandBufferBeginInfo(
            flags=vulkan.VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
            pInheritanceInfo=None)

        vulkan.vkBeginCommandBuffer(self.vk_command_buffer, begin)
Beispiel #2
0
    def buildCommandBuffers(self):
        cmdBufInfo = vk.VkCommandBufferBeginInfo(
            sType=vk.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, pNext=None)
        clearValues = []
        clearValue = vk.VkClearValue(color=self.defaultClearColor)
        clearValues.append(clearValue)
        clearValue = vk.VkClearValue(depthStencil=[1.0, 0])
        clearValues.append(clearValue)
        offset = vk.VkOffset2D(x=0, y=0)
        extent = vk.VkExtent2D(width=self.width, height=self.height)
        renderArea = vk.VkRect2D(offset=offset, extent=extent)
        renderPassBeginInfo = vk.VkRenderPassBeginInfo(
            sType=vk.VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
            pNext=None,
            renderPass=self.renderPass,
            renderArea=renderArea,
            clearValueCount=2,
            pClearValues=clearValues,
        )
        for i in range(len(self.drawCmdBuffers)):
            renderPassBeginInfo.framebuffer = self.frameBuffers[i]
            vk.vkBeginCommandBuffer(self.drawCmdBuffers[i], cmdBufInfo)
            vk.vkCmdBeginRenderPass(self.drawCmdBuffers[i],
                                    renderPassBeginInfo,
                                    vk.VK_SUBPASS_CONTENTS_INLINE)
            viewport = vk.VkViewport(height=float(self.height),
                                     width=float(self.width),
                                     minDepth=0.0,
                                     maxDepth=1.0)
            vk.vkCmdSetViewport(self.drawCmdBuffers[i], 0, 1, [viewport])
            # Update dynamic scissor state
            offsetscissor = vk.VkOffset2D(x=0, y=0)
            extentscissor = vk.VkExtent2D(width=self.width, height=self.height)
            scissor = vk.VkRect2D(offset=offsetscissor, extent=extentscissor)
            vk.vkCmdSetScissor(self.drawCmdBuffers[i], 0, 1, [scissor])

            vk.vkCmdBindDescriptorSets(self.drawCmdBuffers[i],
                                       vk.VK_PIPELINE_BIND_POINT_GRAPHICS,
                                       self.pipelineLayout, 0, 1,
                                       [self.descriptorSet], 0, None)
            vk.vkCmdBindPipeline(self.drawCmdBuffers[i],
                                 vk.VK_PIPELINE_BIND_POINT_GRAPHICS,
                                 self.pipelines['solid'])

            offsets = [0]
            vk.vkCmdBindVertexBuffers(self.drawCmdBuffers[i],
                                      VERTEX_BUFFER_BIND_ID, 1,
                                      [self.vertexBuffer.buffer], offsets)
            vk.vkCmdBindIndexBuffer(self.drawCmdBuffers[i],
                                    self.indexBuffer.buffer, 0,
                                    vk.VK_INDEX_TYPE_UINT32)
            # Draw indexed triangle
            vk.vkCmdDrawIndexed(self.drawCmdBuffers[i], self.indexCount, 1, 0,
                                0, 0)
            self.drawUI(self.drawCmdBuffers[i])
            vk.vkCmdEndRenderPass(self.drawCmdBuffers[i])
            vk.vkEndCommandBuffer(self.drawCmdBuffers[i])
Beispiel #3
0
    def getCommandBuffer(self, begin):
        """
Get a new command buffer from the command pool
If begin is true, the command buffer is also started so we can start adding commands
        """
        cmdBufAllocateInfo = vk.VkCommandBufferAllocateInfo(
            sType=vk.VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
            commandPool=self.cmdPool,
            level=vk.VK_COMMAND_BUFFER_LEVEL_PRIMARY,
            commandBufferCount=1)
        cmdBuffer = vk.vkAllocateCommandBuffers(self.device,
                                                cmdBufAllocateInfo)[0]

        if begin:
            cmdBufInfo = vk.VkCommandBufferBeginInfo(
                sType=vk.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO)
            vk.vkBeginCommandBuffer(cmdBuffer, cmdBufInfo)
        return cmdBuffer
Beispiel #4
0
    def buildCommandBuffers(self):
        cmdBufInfo = vk.VkCommandBufferBeginInfo(
            sType=vk.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO)
        clearValues = []
        clearValue = vk.VkClearValue(color=self.defaultClearColor)
        clearValues.append(clearValue)
        clearValue = vk.VkClearValue(depthStencil=[1.0, 0])
        clearValues.append(clearValue)
        offset = vk.VkOffset2D(x=0, y=0)
        extent = vk.VkExtent2D(width=self.width, height=self.height)
        renderArea = vk.VkRect2D(offset=offset, extent=extent)
        renderPassBeginInfo = vk.VkRenderPassBeginInfo(
            sType=vk.VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
            pNext=None,
            renderPass=self.renderPass,
            renderArea=renderArea,
            clearValueCount=2,
            pClearValues=clearValues,
        )
        for i in range(len(self.drawCmdBuffers)):
            renderPassBeginInfo.framebuffer = self.frameBuffers[i]
            vk.vkBeginCommandBuffer(self.drawCmdBuffers[i], cmdBufInfo)
            vk.vkCmdBeginRenderPass(self.drawCmdBuffers[i],
                                    renderPassBeginInfo,
                                    vk.VK_SUBPASS_CONTENTS_INLINE)
            viewport = vk.VkViewport(height=float(self.height),
                                     width=float(self.width),
                                     minDepth=0.0,
                                     maxDepth=1.0)
            vk.vkCmdSetViewport(self.drawCmdBuffers[i], 0, 1, [viewport])
            # Update dynamic scissor state
            offsetscissor = vk.VkOffset2D(x=0, y=0)
            extentscissor = vk.VkExtent2D(width=self.width, height=self.height)
            scissor = vk.VkRect2D(offset=offsetscissor, extent=extentscissor)
            vk.vkCmdSetScissor(self.drawCmdBuffers[i], 0, 1, [scissor])

            self.scene.render(self.drawCmdBuffers[i], self.wireframe)
            #self.scene.render(self.drawCmdBuffers[i], True)
            self.drawUI(self.drawCmdBuffers[i])
            vk.vkCmdEndRenderPass(self.drawCmdBuffers[i])
            vk.vkEndCommandBuffer(self.drawCmdBuffers[i])
Beispiel #5
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()
Beispiel #6
0
    def buildCommandBuffers(self):
        """
Build separate command buffers for every framebuffer image
Unlike in OpenGL all rendering commands are recorded once into command buffers that are then resubmitted to the queue
This allows to generate work upfront and from multiple threads, one of the biggest advantages of Vulkan
        """
        cmdBufInfo = vk.VkCommandBufferBeginInfo(
            sType=vk.VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, pNext=None)
        # Set clear values for all framebuffer attachments with loadOp set to clear
        # We use two attachments (color and depth) that are cleared at the start of the subpass and as such we need to set clear values for both
        clearValues = []
        clearValue = vk.VkClearValue(color=[[0.0, 0.0, 0.2, 1.0]])
        clearValues.append(clearValue)
        clearValue = vk.VkClearValue(depthStencil=[1.0, 0])
        clearValues.append(clearValue)
        offset = vk.VkOffset2D(x=0, y=0)
        extent = vk.VkExtent2D(width=self.width, height=self.height)
        renderArea = vk.VkRect2D(offset=offset, extent=extent)
        for i in range(len(self.drawCmdBuffers)):
            renderPassBeginInfo = vk.VkRenderPassBeginInfo(
                sType=vk.VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
                pNext=None,
                renderPass=self.renderPass,
                renderArea=renderArea,
                clearValueCount=2,
                pClearValues=clearValues,
                # Set target frame buffer
                framebuffer=self.frameBuffers[i])
            # wait this buffer to be released
            #vk.vkWaitForFences(self.device, 1, [self.waitFences[i]], vk.VK_TRUE, vk.UINT64_MAX)
            # rebuild this buffer
            vk.vkBeginCommandBuffer(self.drawCmdBuffers[i], cmdBufInfo)
            # Start the first sub pass specified in our default render pass setup by the base class
            # This will clear the color and depth attachment
            vk.vkCmdBeginRenderPass(self.drawCmdBuffers[i],
                                    renderPassBeginInfo,
                                    vk.VK_SUBPASS_CONTENTS_INLINE)
            # Update dynamic viewport state
            viewport = vk.VkViewport(height=float(self.height),
                                     width=float(self.width),
                                     minDepth=0.0,
                                     maxDepth=1.0)
            vk.vkCmdSetViewport(self.drawCmdBuffers[i], 0, 1, [viewport])
            # Update dynamic scissor state
            offsetscissor = vk.VkOffset2D(x=0, y=0)
            extentscissor = vk.VkExtent2D(width=self.width, height=self.height)
            scissor = vk.VkRect2D(offset=offsetscissor, extent=extentscissor)
            vk.vkCmdSetScissor(self.drawCmdBuffers[i], 0, 1, [scissor])

            # Bind descriptor sets describing shader binding points
            vk.vkCmdBindDescriptorSets(self.drawCmdBuffers[i],
                                       vk.VK_PIPELINE_BIND_POINT_GRAPHICS,
                                       self.pipelineLayout, 0, 1,
                                       [self.descriptorSet], 0, None)
            # Bind the rendering pipeline
            # The pipeline (state object) contains all states of the rendering pipeline, binding it will set all the states specified at pipeline creation time
            vk.vkCmdBindPipeline(self.drawCmdBuffers[i],
                                 vk.VK_PIPELINE_BIND_POINT_GRAPHICS,
                                 self.pipeline)
            # Bind triangle vertex buffer (contains position and colors)
            offsets = [0]
            vk.vkCmdBindVertexBuffers(self.drawCmdBuffers[i], 0, 1,
                                      [self.vertices['buffer']], offsets)
            # Bind triangle index buffer
            vk.vkCmdBindIndexBuffer(self.drawCmdBuffers[i],
                                    self.indices['buffer'], 0,
                                    vk.VK_INDEX_TYPE_UINT32)
            # Draw indexed triangle
            vk.vkCmdDrawIndexed(self.drawCmdBuffers[i], self.indices['count'],
                                1, 0, 0, 1)
            # uncomment for imgui support
            self.drawUI(self.drawCmdBuffers[i])
            vk.vkCmdEndRenderPass(self.drawCmdBuffers[i])
            # Ending the render pass will add an implicit barrier transitioning the frame buffer color attachment to
            # VK_IMAGE_LAYOUT_PRESENT_SRC_KHR for presenting it to the windowing system
            vk.vkEndCommandBuffer(self.drawCmdBuffers[i])