Esempio n. 1
0
def mesh_to_staging():
    global staging_mesh_buffer, staging_mesh_memory

    # Create staging resources
    staging_mesh_buffer = hvk.create_buffer(
        api, device,
        hvk.buffer_create_info(size=total_mesh_size,
                               usage=vk.BUFFER_USAGE_TRANSFER_SRC_BIT))

    staging_req = hvk.buffer_memory_requirements(api, device,
                                                 staging_mesh_buffer)
    mt_index = find_memory_type(
        0, vk.MEMORY_PROPERTY_HOST_COHERENT_BIT
        | vk.MEMORY_PROPERTY_HOST_VISIBLE_BIT)

    staging_mesh_memory = hvk.allocate_memory(
        api, device,
        hvk.memory_allocate_info(allocation_size=staging_req.size,
                                 memory_type_index=mt_index))

    hvk.bind_buffer_memory(api, device, staging_mesh_buffer,
                           staging_mesh_memory, 0)

    # Upload mesh to staging data
    data_ptr = hvk.map_memory(api, device, staging_mesh_memory, 0,
                              staging_req.size).value

    memmove(data_ptr + mesh_positions['offset'], byref(mesh_positions['data']),
            mesh_positions['size'])
    memmove(data_ptr + mesh_indices['offset'], byref(mesh_indices['data']),
            mesh_indices['size'])

    hvk.unmap_memory(api, device, staging_mesh_memory)
def texture_to_staging():
    global staging_texture_buffer, staging_texture_memory

    # Create staging resources
    staging_texture_buffer = hvk.create_buffer(
        api, device,
        hvk.buffer_create_info(size=len(texture.data),
                               usage=vk.BUFFER_USAGE_TRANSFER_SRC_BIT))

    staging_req = hvk.buffer_memory_requirements(api, device,
                                                 staging_texture_buffer)
    mt_index = find_memory_type(
        0, vk.MEMORY_PROPERTY_HOST_COHERENT_BIT
        | vk.MEMORY_PROPERTY_HOST_VISIBLE_BIT)
    staging_texture_memory = hvk.allocate_memory(
        api, device,
        hvk.memory_allocate_info(allocation_size=staging_req.size,
                                 memory_type_index=mt_index))

    hvk.bind_buffer_memory(api, device, staging_texture_buffer,
                           staging_texture_memory, 0)

    # Upload texture to staging data
    data_ptr = hvk.map_memory(api, device, staging_texture_memory, 0,
                              staging_req.size).value

    memmove(data_ptr, texture.data_ptr(), len(texture.data))

    hvk.unmap_memory(api, device, staging_texture_memory)
Esempio n. 3
0
    def _setup_meshes_resources(self, staging_alloc, staging_buffer,
                                mesh_buffer_size):
        engine, api, device = self.ctx
        mem = engine.memory_manager
        cmd = engine.setup_command_buffer

        # Final buffer allocation
        mesh_buffer = hvk.create_buffer(
            api, device,
            hvk.buffer_create_info(size=mesh_buffer_size,
                                   usage=vk.BUFFER_USAGE_INDEX_BUFFER_BIT
                                   | vk.BUFFER_USAGE_VERTEX_BUFFER_BIT
                                   | vk.BUFFER_USAGE_TRANSFER_DST_BIT))
        mesh_alloc = mem.alloc(mesh_buffer,
                               vk.STRUCTURE_TYPE_BUFFER_CREATE_INFO,
                               (vk.MEMORY_PROPERTY_DEVICE_LOCAL_BIT, ))

        # Uploading commands
        region = vk.BufferCopy(src_offset=0,
                               dst_offset=0,
                               size=mesh_buffer_size)
        regions = (region, )

        hvk.begin_command_buffer(api, cmd, hvk.command_buffer_begin_info())
        hvk.copy_buffer(api, cmd, staging_buffer, mesh_buffer, regions)
        hvk.end_command_buffer(api, cmd)

        # Submitting
        engine.submit_setup_command(wait=True)

        return mesh_alloc, mesh_buffer
def create_descriptor_sets():
    global descriptor_pool, descriptor_set, uniforms_buffer, uniforms_mem
    global ubo_data_type, light_data_type, uniforms_data_type

    # Setup descriptor set resources
    ubo_data_type = Mat4 * 3
    light_data_type = type(
        "Light", (Structure, ), {
            '_fields_':
            (('reverseLightDirection', c_float * 3), ('color', c_float * 4))
        })
    uniforms_data_type = type(
        "Uniforms", (Structure, ),
        {'_fields_': (('ubo', ubo_data_type), ('light', light_data_type))})
    uniforms_data_size = sizeof(uniforms_data_type)

    # Create descriptor pool
    uniforms_pool_size = vk.DescriptorPoolSize(
        type=vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER, descriptor_count=2)

    sampler_pool_size = vk.DescriptorPoolSize(
        type=vk.DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, descriptor_count=1)

    descriptor_pool = hvk.create_descriptor_pool(
        api, device,
        hvk.descriptor_pool_create_info(max_sets=1,
                                        pool_sizes=(uniforms_pool_size,
                                                    sampler_pool_size)))

    descriptor_set = hvk.allocate_descriptor_sets(
        api, device,
        hvk.descriptor_set_allocate_info(
            descriptor_pool=descriptor_pool,
            set_layouts=(descriptor_set_layout, )))[0]

    # Allocate memory for the descriptor
    uniforms_buffer = hvk.create_buffer(
        api, device,
        hvk.buffer_create_info(size=uniforms_data_size,
                               usage=vk.BUFFER_USAGE_UNIFORM_BUFFER_BIT))

    ubo_buffer_req = hvk.buffer_memory_requirements(api, device,
                                                    uniforms_buffer)
    mt_index = find_memory_type(
        0, vk.MEMORY_PROPERTY_HOST_COHERENT_BIT
        | vk.MEMORY_PROPERTY_HOST_VISIBLE_BIT)

    uniforms_mem = hvk.allocate_memory(
        api, device,
        hvk.memory_allocate_info(allocation_size=ubo_buffer_req.size,
                                 memory_type_index=mt_index))

    hvk.bind_buffer_memory(api, device, uniforms_buffer, uniforms_mem, 0)
def create_descriptor_sets():
    global descriptor_pool, descriptor_set, color_buffer, color_mem

    # Uniform buffer values
    colors = (0.8, 0.8, 0.0, 1.0)
    colors_data = (c_float * len(colors))(*colors)
    colors_data_size = sizeof(colors_data)

    # Create descriptor pool
    pool_size = vk.DescriptorPoolSize(type=vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER,
                                      descriptor_count=1)

    descriptor_pool = hvk.create_descriptor_pool(
        api, device,
        hvk.descriptor_pool_create_info(max_sets=1, pool_sizes=(pool_size, )))

    descriptor_set = hvk.allocate_descriptor_sets(
        api, device,
        hvk.descriptor_set_allocate_info(
            descriptor_pool=descriptor_pool,
            set_layouts=(descriptor_set_layout, )))[0]

    # Allocate memory for the descriptor
    color_buffer = hvk.create_buffer(
        api, device,
        hvk.buffer_create_info(size=colors_data_size,
                               usage=vk.BUFFER_USAGE_UNIFORM_BUFFER_BIT))

    color_buffer_req = hvk.buffer_memory_requirements(api, device,
                                                      color_buffer)
    mt_index = find_memory_type(
        0, vk.MEMORY_PROPERTY_HOST_COHERENT_BIT
        | vk.MEMORY_PROPERTY_HOST_VISIBLE_BIT)

    color_mem = hvk.allocate_memory(
        api, device,
        hvk.memory_allocate_info(allocation_size=color_buffer_req.size,
                                 memory_type_index=mt_index))

    hvk.bind_buffer_memory(api, device, color_buffer, color_mem, 0)

    # Upload color data to memory
    data_ptr = hvk.map_memory(api, device, color_mem, 0,
                              colors_data_size).value

    memmove(data_ptr, byref(colors_data), colors_data_size)

    hvk.unmap_memory(api, device, color_mem)
def mesh_to_device():
    global mesh_buffer, mesh_memory, staging_mesh_buffer, staging_mesh_memory, mesh_data

    # Create mesh resources
    mesh_buffer = hvk.create_buffer(
        api, device,
        hvk.buffer_create_info(size=total_mesh_size,
                               usage=vk.BUFFER_USAGE_TRANSFER_DST_BIT
                               | vk.BUFFER_USAGE_INDEX_BUFFER_BIT
                               | vk.BUFFER_USAGE_VERTEX_BUFFER_BIT))

    mesh_req = hvk.buffer_memory_requirements(api, device, mesh_buffer)
    mt_index = find_memory_type(vk.MEMORY_HEAP_DEVICE_LOCAL_BIT,
                                vk.MEMORY_PROPERTY_DEVICE_LOCAL_BIT)

    mesh_memory = hvk.allocate_memory(
        api, device,
        hvk.memory_allocate_info(allocation_size=mesh_req.size,
                                 memory_type_index=mt_index))

    hvk.bind_buffer_memory(api, device, mesh_buffer, mesh_memory, 0)

    # Upload mesh to device memory (recording)
    hvk.begin_command_buffer(api, staging_cmd, hvk.command_buffer_begin_info())

    region = vk.BufferCopy(src_offset=0, dst_offset=0, size=mesh_req.size)
    hvk.copy_buffer(api, staging_cmd, staging_mesh_buffer, mesh_buffer,
                    (region, ))

    hvk.end_command_buffer(api, staging_cmd)

    # Upload mesh to device memory (submiting)
    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, ))

    # Free staging resources
    hvk.destroy_buffer(api, device, staging_mesh_buffer)
    hvk.free_memory(api, device, staging_mesh_memory)
    del mesh_data, staging_mesh_buffer, staging_mesh_memory
Esempio n. 7
0
    def _setup_objects_staging(self, staging_size, data_meshes, data_images):
        engine, api, device = self.ctx
        mem = engine.memory_manager

        staging_buffer = hvk.create_buffer(
            api, device,
            hvk.buffer_create_info(size=staging_size,
                                   usage=vk.BUFFER_USAGE_TRANSFER_SRC_BIT))
        staging_alloc = mem.alloc(staging_buffer,
                                  vk.STRUCTURE_TYPE_BUFFER_CREATE_INFO,
                                  (vk.MEMORY_PROPERTY_HOST_COHERENT_BIT
                                   | vk.MEMORY_PROPERTY_HOST_VISIBLE_BIT, ))

        with mem.map_alloc(staging_alloc) as alloc:
            for dm in data_meshes:
                alloc.write_bytes(dm.base_offset, dm.as_ctypes_array())

            for di in data_images:
                alloc.write_bytes(di.base_staging_offset, di.as_ctypes_array())

        return staging_alloc, staging_buffer
Esempio n. 8
0
    def _setup_descriptor_sets(self):
        engine, api, device = self.ctx
        shaders, computes = self.shaders, self.computes
        descriptor_pool = self.descriptor_pool
        mem = engine.memory_manager

        uniforms_buffer_size = 0

        # Allocate shader global descriptor sets
        for data_shader in shaders:
            uniforms_buffer_size += sum(l.struct_map_size_bytes
                                        for l in data_shader.global_layouts)
            set_layouts_global = [
                l.set_layout for l in data_shader.global_layouts
            ]

            if len(set_layouts_global) == 0:
                data_shader.descriptor_sets = []
                continue

            descriptor_sets = hvk.allocate_descriptor_sets(
                api, device,
                hvk.descriptor_set_allocate_info(
                    descriptor_pool=descriptor_pool,
                    set_layouts=set_layouts_global))

            data_shader.descriptor_sets = descriptor_sets

        # Allocate compute shader global descriptor sets
        for data_compute in computes:
            uniforms_buffer_size += sum(l.struct_map_size_bytes
                                        for l in data_compute.global_layouts)
            set_layouts_global = [
                l.set_layout for l in data_compute.global_layouts
            ]

            if len(set_layouts_global) == 0:
                data_compute.descriptor_sets = []
                continue

            descriptor_sets = hvk.allocate_descriptor_sets(
                api, device,
                hvk.descriptor_set_allocate_info(
                    descriptor_pool=descriptor_pool,
                    set_layouts=set_layouts_global))

            data_compute.descriptor_sets = descriptor_sets

        # Allocate object local descriptor sets
        for shader_index, objects in self._group_objects_by_shaders():
            shader = shaders[shader_index]
            objlen = len(objects)

            # Uniforms buffer size
            uniforms_buffer_size += sum(l.struct_map_size_bytes
                                        for l in shader.local_layouts) * objlen

            # Descriptor sets allocations
            set_layouts_local = [l.set_layout
                                 for l in shader.local_layouts] * objlen
            if len(set_layouts_local) == 0:
                for obj in objects:
                    obj.descriptor_sets = []
                continue

            descriptor_sets = hvk.allocate_descriptor_sets(
                api, device,
                hvk.descriptor_set_allocate_info(
                    descriptor_pool=descriptor_pool,
                    set_layouts=set_layouts_local))

            # Save the local layouts to the objects
            step = len(tuple(shader.local_layouts))
            if step == 0:
                continue

            end = len(descriptor_sets)
            iter_objects = iter(objects)
            for i in range(0, end, step):
                obj = next(iter_objects)
                obj.descriptor_sets = descriptor_sets[i:i + step]

        # Uniform buffer creation
        if uniforms_buffer_size == 0:
            self.uniforms_alloc = self.uniforms_buffer = None
            return

        uniforms_buffer = hvk.create_buffer(
            api, device,
            hvk.buffer_create_info(size=uniforms_buffer_size,
                                   usage=vk.BUFFER_USAGE_UNIFORM_BUFFER_BIT))
        uniforms_alloc = mem.alloc(uniforms_buffer,
                                   vk.STRUCTURE_TYPE_BUFFER_CREATE_INFO,
                                   (vk.MEMORY_PROPERTY_HOST_VISIBLE_BIT
                                    | vk.MEMORY_PROPERTY_HOST_COHERENT_BIT, ))

        # Make sure the uniforms are zeroed
        with mem.map_alloc(uniforms_alloc) as mapping:
            memset(mapping.pointer2, 0, uniforms_alloc.size)

        self.uniforms_alloc = uniforms_alloc
        self.uniforms_buffer = uniforms_buffer