{.experimental: "codeReordering".} {.deadCodeElim: on.} #TODO: REBUILD render_Pass_begin_info on window size change import ../vk/[ vulkan_record , vulkan_utils , vulkan , depth_stencil , swapchain , buffer ] , scene_object , scene_record , ../deshn_entity/[ being ] , ../drawable/[ shape_object , text_types , plane ] , ../wain/[ waindow_object ] , std/[ tables , bitops ] , glm proc a_scene*( vk_record: var Vulkan_Record ): Scene = result = Scene() result.entities = newTable[string, int]() proc theIds*(scene: Scene): seq[int] = for t in scene.shapes: result.add t.id proc theNames*(scene: Scene): seq[string] = for t in scene.shapes: result.add t.name proc the_shape*( scene: var Scene , id: int , name: string ): var Shape = for t in scene.shapes.mitems: if t.id == id: return t quit("ERROR: Entity[SHAPE] not found: " & name & ": id" & $id) proc the_shape*( scene: var Scene , name: string ): var Shape = scene.the_shape scene.entities[name], name proc the_deshn_being*( scene: var Scene , id: int , name: string ): var Deshn_Being = for t in scene.deshn_beings.mitems: if t.id == id: return t quit("ERROR: Entity[SHAPE] not found: " & name & ": id" & $id) proc the_deshn_being*( scene: var Scene , name: string ): var Deshn_Being = scene.the_deshn_being scene.entities[name], name #[ proc the_text*( scene: Scene , id: int , name: string ): var SDFText = #WARNING]: Cannot prove that 'result' is initialized. This will become a compile time error in the future. [ProveInit] for t in scene.texts.mitems: if t.id == id: return t quit("ERROR: Entity[SDFTEXT] not found: " & name & " / id:" & $id) proc the_text*( scene: Scene , name: string ): var SDFText = scene.the_text scene.entities[name], name ]# # # TODO: need drawable-independent command buffers # proc build*( vk_record: Vulkan_Record # , scene: var Scene # ) = proc the_plane*( scene: var Scene , id: int , name: string ): var Plane = for t in scene.planes.mitems: if t.id == id: return t quit("ERROR: Entity[SHAPE] not found: " & name & ": id" & $id) proc the_plane*( scene: var Scene , name: string ): var Plane = scene.the_plane scene.entities[name], name proc add*( scene: var Scene , shape: Shape ) = #echo "adding: ", sh.name, " ", sh.id scene.shapes.add shape scene.entities[shape.name] = shape.id scene.current_entity_id += 1 scene.the_vertices.add shape.vertices scene.the_indices.add shape.indices #[ proc add*( scene: var Scene , text: SDFText ) = scene.texts.add text scene.entities[text.name] = scene.current_entity_id scene.current_entity_id += 1 for text_vert in text.vertices: scene.the_vertices.add text_vert.pos.x scene.the_vertices.add text_vert.pos.y scene.the_vertices.add text_vert.pos.z scene.the_vertices.add text_vert.uv.x scene.the_vertices.add text_vert.uv.y scene.the_indices.add text.indices ]# proc add*( scene: var Scene , deshn_being: Deshn_Being ) = #echo "adding: ", sh.name, " ", sh.id scene.deshn_beings.add deshn_being scene.entities[deshn_being.name] = deshn_being.id scene.current_entity_id += 1 scene.add deshn_being.shape proc add*( scene: var Scene , plane: Plane ) = #echo "adding: ", sh.name, " ", sh.id scene.planes.add plane scene.entities[plane.name] = plane.id scene.current_entity_id += 1 scene.add plane.shape proc prepare_vertices*( scene: var Scene , vk_device: VkDevice , memory_properties: VkPhysicalDeviceMemoryProperties , command_pool: VkCommandPool , queue: VkQueue , master_vertex_buffer: var Buffer , master_index_buffer: var Buffer ) = var copyCmd: VkCommandBuffer = vk_device.getCommandBuffers(command_pool, true) copyRegion: VkBufferCopy data: pointer #[ copyMem( data, addr scene.the_vertices[0] , Natural scene.the_vertices.sizeof ) vkUnmapMemory( vk_device , scene.staging_vertex_buffer.device_memory ) discard vkBindBufferMemory( vk_device , scene.staging_vertex_buffer.vkbuffer , scene.staging_vertex_buffer.device_memory , VkDeviceSize 0 ) discard vkBindBufferMemory( vk_device , scene.vertex_buffer.vkbuffer , scene.vertex_buffer.device_memory , VkDeviceSize 0 ) scene.staging_index_buffer = a_vulkan_buffer( vk_device , memory_properties , VkBufferUsageFlags VK_BUFFER_USAGE_TRANSFER_SRC_BIT , VkMemoryPropertyFlags bitor( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT.ord , VK_MEMORY_PROPERTY_HOST_COHERENT_BIT.ord ) , VkDeviceSize scene.the_indices.sizeof ) scene.index_buffer = a_vulkan_buffer( vk_device , memory_properties , VkBufferUsageFlags bitor(VK_BUFFER_USAGE_INDEX_BUFFER_BIT.ord, VK_BUFFER_USAGE_TRANSFER_DST_BIT.ord) , VkMemoryPropertyFlags VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT , VkDeviceSize scene.the_indices.sizeof ) vk_device.map_memory( scene.staging_index_buffer.device_memory , data ) copyMem(data, addr scene.the_indices[0], Natural scene.the_indices.sizeof) vkUnmapMemory(vk_device, scene.staging_index_buffer.device_memory) discard vkBindBufferMemory(vk_device, scene.staging_index_buffer.vkbuffer, scene.staging_index_buffer.device_memory, VkDeviceSize 0) discard vkBindBufferMemory(vk_device, scene.index_buffer.vkbuffer, scene.index_buffer.device_memory, VkDeviceSize 0) copyRegion.size = VkDeviceSize scene.the_vertices.sizeof vkCmdCopyBuffer(copyCmd, scene.staging_vertex_buffer.vkbuffer, scene.vertex_buffer.vkbuffer, 1.uint32, addr copyRegion) copyRegion.size = VkDeviceSize scene.the_indices.sizeof vkCmdCopyBuffer(copyCmd, scene.staging_index_buffer.vkbuffer, scene.index_buffer.vkbuffer, 1.uint32, addr copyRegion) # # Flushing the command buffer will also submit it to the queue and # # uses a fence to ensure that all commands have been executed before returning vk_device.flushCommandBuffer queue, command_pool, copyCmd # Destroy staging buffers # Note: Staging buffer must not be deleted before the copies have been submitted and executed vkDestroyBuffer( vk_device , scene.staging_vertex_buffer.vkbuffer , nil ) vkFreeMemory( vk_device , scene.staging_vertex_buffer.device_memory , nil ) vkDestroyBuffer( vk_device , scene.staging_index_buffer.vkbuffer , nil ) vkFreeMemory( vk_device , scene.staging_index_buffer.device_memory , nil ) ]# proc clean_up*( vk_record: var Vulkan_Record , scene: var Scene ) = discard vkDeviceWaitIdle vk_record.vk_device # recycle the Pools! # vkDestroyDescriptorPool(demo->device, demo->desc_pool, NULL) # vkDestroyCommandPool(demo->device, demo->command_pool, NULL); #should we have an initial "setup command buffer"? #[ for shape in scene.shapes: vk_record.vk_device.vkDestroyPipeline(shape.graphicsPipeline.pipeline, nil) vk_record.vk_device.vkDestroyPipelineLayout(shape.graphicsPipeline.pipelineLayout, nil) vk_record.vk_device.vkDestroyDescriptorSetLayout(shape.descrSetLayout, nil) for text in scene.texts: vk_record.vk_device.vkDestroyPipeline(text.graphicsPipeline.pipeline, nil) vk_record.vk_device.vkDestroyPipelineLayout(text.graphicsPipeline.pipelineLayout, nil) vk_record.vk_device.vkDestroyDescriptorSetLayout(text.descrSetLayout, nil) ]# #[ for i,fb in vk_record.draw_command_buffers: vkFreeCommandBuffers( vk_record.vk_device , vk_record.command_pool , 1 , addr vk_record.draw_command_buffers[i] ) vk_record.vk_device.vkDestroyRenderPass(scene.render_pass, nil) ]# #[ proc rebuild_render_pass_info*( vk_record: var Vulkan_Record , scene: var Scene ) = var scissor = VkRect2D( extent: VkExtent2D( width: uint32 vk_record.swapchain.current_extent.width , height: uint32 vk_record.swapchain.current_extent.height ) , offset: VkOffset2D( x: 0 , y: 0 ) ) renderPassBeginInfo = VkRenderPassBeginInfo(sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO) clearValues: array[2,VkClearValue] clearValues[0].color = VkClearColorValue(float32: [0f, 0f, 0f, 1f]) clearValues[1].depth_stencil = VkClearDepthStencilValue( depth: 1.0f , stencil: 0 ) renderPassBeginInfo.pNext = nil renderPassBeginInfo.renderArea.offset.x = 0 renderPassBeginInfo.renderArea.offset.y = 0 renderPassBeginInfo.renderArea.extent.width = uint32 vk_record.swapchain.current_extent.width renderPassBeginInfo.renderArea.extent.height = uint32 vk_record.swapchain.current_extent.height renderPassBeginInfo.clearValueCount = 2 renderPassBeginInfo.pClearValues = addr clearValues[0] renderPassBeginInfo.render_pass = scene.render_pass renderPassBeginInfo.framebuffer = vk_record.frame_buffers[vk_record.currentFrameBuffer] scene[].render_pass_begin_info = renderPassBeginInfo scene[].scissor = scissor ]#