Пример #1
0
def create_descriptor_set_layout():
    global descriptor_set_layout

    ubo_binding = hvk.descriptor_set_layout_binding(
        binding=0,
        descriptor_type=vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER,
        descriptor_count=1,
        stage_flags=vk.SHADER_STAGE_VERTEX_BIT)

    light_binding = hvk.descriptor_set_layout_binding(
        binding=1,
        descriptor_type=vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER,
        descriptor_count=1,
        stage_flags=vk.SHADER_STAGE_FRAGMENT_BIT)

    mat_binding = hvk.descriptor_set_layout_binding(
        binding=2,
        descriptor_type=vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER,
        descriptor_count=1,
        stage_flags=vk.SHADER_STAGE_FRAGMENT_BIT)

    # Setup shader descriptor set
    info = hvk.descriptor_set_layout_create_info(bindings=(ubo_binding,
                                                           light_binding,
                                                           mat_binding))
    descriptor_set_layout = hvk.create_descriptor_set_layout(api, device, info)
Пример #2
0
def create_compute_descriptor_set_layout():
    global compute_descriptor_set_layout

    noise_binding = hvk.descriptor_set_layout_binding(
        binding=0,
        descriptor_type=vk.DESCRIPTOR_TYPE_STORAGE_IMAGE,
        descriptor_count=1,
        stage_flags=vk.SHADER_STAGE_COMPUTE_BIT)

    # Setup shader descriptor set
    info = hvk.descriptor_set_layout_create_info(bindings=(noise_binding, ))
    compute_descriptor_set_layout = hvk.create_descriptor_set_layout(
        api, device, info)
Пример #3
0
def create_descriptor_set_layout():
    global descriptor_set_layout

    # Setup shader descriptor set
    info = hvk.descriptor_set_layout_create_info(bindings=())
    descriptor_set_layout = hvk.create_descriptor_set_layout(api, device, info)
Пример #4
0
def setup_descriptor_layouts(shader, engine, api, device, mappings):

    if len(mappings["uniforms"]) == 0:
        return

    # Uniform buffers offsets MUST absolutly be aligned to minUniformBufferOffsetAlignment
    # On AMD: 16 bytes
    # On INTEL: 32 bytes
    # On NVDIA, 256 bits
    limits = engine.info["limits"]
    uniform_buffer_align = limits.min_uniform_buffer_offset_alignment

    layouts = []

    def init_fn(me, **defaults):
        me_cls = type(me)
        members = [name for name, _ in me_cls._fields_]
        bad_members = [m for m in defaults.keys() if not m in members]
        if len(bad_members) > 0:
            print(
                f"WARNING: some unkown members were found when creating uniform \"{me_cls.__qualname__}\": {bad_members}"
            )

        super(me_cls, me).__init__(**defaults)

    def repr_fn(me):
        type_name = type(me).__qualname__
        fields = {}
        for name, ctype in me._fields_:
            value = getattr(me, name)
            if hasattr(value, '_length_'):
                fields[name] = value[::]
            else:
                fields[name] = value

        return f"Uniform(name={type_name}, fields={repr(fields)})"

    for dset, uniforms in group_uniforms_by_sets(mappings):
        counts, structs, images, bindings, wst = {}, {}, [], [], []

        for uniform in uniforms:
            uniform_name, dtype, dcount, ubinding = uniform["name"], uniform[
                "type"], uniform["count"], uniform["binding"]
            buffer = True

            # Counts used for the descriptor pool max capacity
            if dtype in counts:
                counts[dtype] += dcount
            else:
                counts[dtype] = dcount

            # ctypes Struct used when allocating uniforms buffers
            struct_size = None
            if dtype in (vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER,
                         vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC):
                size_of = 0
                args = []
                for field in uniform["fields"]:
                    field_name = field["name"]
                    field_ctype = uniform_member_as_ctype(
                        field["type"], field["count"])
                    size_of += sizeof(field_ctype)
                    args.append((field_name, field_ctype))

                padding = (-size_of & (uniform_buffer_align - 1))
                if padding > 0:
                    args.append(("PADDING", c_uint8 * padding))

                struct = type(
                    uniform_name, (Structure, ), {
                        '_pack_': 16,
                        '_fields_': args,
                        '__init__': init_fn,
                        '__repr__': repr_fn
                    })
                struct_size = sizeof(struct)
                structs[uniform_name] = struct
            elif dtype in (vk.DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
                           vk.DESCRIPTOR_TYPE_STORAGE_IMAGE):
                images.append(uniform_name)
                buffer = False
            else:
                raise NotImplementedError(
                    f"Descriptor type {dtype} not implemented")

            # Bindings for raw set layout creation
            binding = hvk.descriptor_set_layout_binding(
                binding=ubinding,
                descriptor_type=dtype,
                descriptor_count=dcount,
                stage_flags=uniform["stage"])

            bindings.append(binding)

            # Write set template. Used during descriptor set creation
            wst.append({
                "name": uniform_name,
                "descriptor_type": dtype,
                "range": struct_size,
                "binding": ubinding,
                "buffer": buffer
            })

        # Associate the values to the descriptor set layout wrapper
        info = hvk.descriptor_set_layout_create_info(bindings=bindings)
        dset_layout = DescriptorSetLayout(
            set_layout=hvk.create_descriptor_set_layout(api, device, info),
            scope=dset["scope"],
            struct_map=structs,
            images=images,
            pool_size_counts=tuple(counts.items()),
            write_set_templates=wst,
        )

        layouts.append(dset_layout)

    return layouts