def record_render_commands(): # Render commands recording begin_info = hvk.command_buffer_begin_info() width, height = window.dimensions() render_pass_begin = hvk.render_pass_begin_info( render_pass=render_pass, framebuffer=0, render_area=hvk.rect_2d(0, 0, width, height), clear_values=(hvk.clear_value(color=(0.0, 0.0, 0.0, 1.0)), hvk.clear_value(depth=1.0, stencil=0))) for framebuffer, cmd in zip(framebuffers, cmd_draw): render_pass_begin.framebuffer = framebuffer hvk.begin_command_buffer(api, cmd, begin_info) hvk.begin_render_pass(api, cmd, render_pass_begin, vk.SUBPASS_CONTENTS_INLINE) hvk.bind_pipeline(api, cmd, pipeline, vk.PIPELINE_BIND_POINT_GRAPHICS) hvk.bind_index_buffer(api, cmd, mesh_buffer, mesh_indices['offset'], vk.INDEX_TYPE_UINT16) hvk.bind_vertex_buffers(api, cmd, (mesh_buffer, ), (mesh_positions['offset'], )) hvk.draw_indexed(api, cmd, mesh_indices['count']) hvk.end_render_pass(api, cmd) hvk.end_command_buffer(api, cmd)
def compute_noise(): hvk.begin_command_buffer(api, staging_cmd, hvk.command_buffer_begin_info()) # Execute the compute shader hvk.bind_pipeline(api, staging_cmd, compute_pipeline, vk.PIPELINE_BIND_POINT_COMPUTE) hvk.bind_descriptor_sets(api, staging_cmd, vk.PIPELINE_BIND_POINT_COMPUTE, compute_pipeline_layout, (compute_descriptor_set, )) hvk.dispatch(api, staging_cmd, 256 // 16, 256 // 16, 1) # Move the image layout to shader read optimal for rendering barrier = hvk.image_memory_barrier( image=noise_image, old_layout=vk.IMAGE_LAYOUT_GENERAL, new_layout=vk.IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, src_access_mask=vk.ACCESS_TRANSFER_WRITE_BIT, dst_access_mask=vk.ACCESS_SHADER_READ_BIT, ) hvk.pipeline_barrier(api, staging_cmd, (barrier, ), dst_stage_mask=vk.PIPELINE_STAGE_FRAGMENT_SHADER_BIT) hvk.end_command_buffer(api, staging_cmd) # Submit the staging command buffer hvk.reset_fences(api, device, (staging_fence, )) submit_info = hvk.submit_info(command_buffers=(staging_cmd, )) hvk.queue_submit(api, render_queue.handle, (submit_info, ), fence=staging_fence) hvk.wait_for_fences(api, device, (staging_fence, ))
def run(self, data_scene, data_compute, group, sync, after, before, callback): if data_compute in self.running: raise RuntimeError(f"Compute shader {data_compute.compute.name} is already running") engine, api, device = self.ctx queue = data_compute.queue cmd = data_scene.compute_commands[data_compute.command_index] pipeline = data_scene.compute_pipelines[data_compute.pipeline] x, y, z = group before = () if before is None else before after = () if after is None else after # Record the commands hvk.begin_command_buffer(api, cmd, hvk.command_buffer_begin_info()) hvk.bind_pipeline(api, cmd, pipeline, vk.PIPELINE_BIND_POINT_COMPUTE) hvk.bind_descriptor_sets(api, cmd, vk.PIPELINE_BIND_POINT_COMPUTE, data_compute.pipeline_layout, data_compute.descriptor_sets) CommandsRunner.run_device(before, api, cmd, queue, data_scene) hvk.dispatch(api, cmd, x, y, z) CommandsRunner.run_device(after, api, cmd, queue, data_scene) hvk.end_command_buffer(api, cmd) # Execute the command buffer cmds = (cmd,) fence = data_compute.fence infos = (hvk.submit_info(command_buffers=cmds),) hvk.queue_submit(api, queue.handle, infos, fence) if sync: f = (fence,) hvk.wait_for_fences(api, device, f) hvk.reset_fences(api, device, f) CommandsRunner.run_app(before, data_scene) CommandsRunner.run_app(after, data_scene) callback() else: self.running.add(data_compute) raise NotImplementedError("Compute without sync is not yet implemented")
def record(self, framebuffer_index): # Caching things locally to improve lookup speed h = hvk engine, api, device = self.ctx cmd = self.render_commands[framebuffer_index] rc = self.render_cache pipelines = self.pipelines pipeline_index = None shaders = self.shaders current_shader_index = None current_shader = None meshes = self.meshes meshes_buffer = self.meshes_buffer # Render pass begin setup render_pass_begin = rc["render_pass_begin_info"] render_pass_begin.framebuffer = engine.render_target.framebuffers[ framebuffer_index] extent = rc["render_area_extent"] extent.width, extent.height = engine.info["swapchain_extent"].values() viewports = rc["viewports"] scissors = rc["scissors"] # Recording h.begin_command_buffer(api, cmd, rc["begin_info"]) h.begin_render_pass(api, cmd, render_pass_begin, vk.SUBPASS_CONTENTS_INLINE) for data_obj in self.objects: obj = data_obj.obj if data_obj.pipeline is not None and pipeline_index != data_obj.pipeline: pipeline_index = data_obj.pipeline hvk.bind_pipeline(api, cmd, pipelines[pipeline_index], vk.PIPELINE_BIND_POINT_GRAPHICS) hvk.set_viewport(api, cmd, viewports) hvk.set_scissor(api, cmd, scissors) if data_obj.shader is not None and current_shader_index != data_obj.shader: current_shader_index = data_obj.shader current_shader = shaders[data_obj.shader] if len(current_shader.descriptor_sets) > 0: hvk.bind_descriptor_sets(api, cmd, vk.PIPELINE_BIND_POINT_GRAPHICS, current_shader.pipeline_layout, current_shader.descriptor_sets) if data_obj.descriptor_sets is not None and len( data_obj.descriptor_sets) > 0: hvk.bind_descriptor_sets(api, cmd, vk.PIPELINE_BIND_POINT_GRAPHICS, current_shader.pipeline_layout, data_obj.descriptor_sets, firstSet=len( current_shader.descriptor_sets)) if data_obj.mesh is not None and not obj.hidden: mesh = meshes[data_obj.mesh] shader = shaders[data_obj.shader] attributes_buffer = [meshes_buffer] * len( mesh.attribute_offsets) attribute_offsets = mesh.attribute_offsets_for_shader(shader) h.bind_index_buffer(api, cmd, meshes_buffer, mesh.indices_offset, mesh.indices_type) h.bind_vertex_buffers(api, cmd, attributes_buffer, attribute_offsets) h.draw_indexed(api, cmd, mesh.indices_count) h.end_render_pass(api, cmd) h.end_command_buffer(api, cmd)