How to populate UIList with all material slot in scene? 2.8
Scene.material_slots

If I understand question you want to display all the materials used by all the objects in the scene.  Every bpy.types.Object has a material slots collection, a scene does not.
Added a material slots collection to the scene.
Used an old fashioned python property to populate Scene.materials from the non None materials on the objects in the scene.
def get_scene_materials(self):    
    return set(s.material for o in self.objects 
            for s in o.material_slots if s.material
            )
bpy.types.Scene.materials = property(get_scene_materials)

To use a UIList AFAIK need the list to be a collection, the index to be an int property.
The scene material slots is not populated automatically. If the set of materials in scene, does not match those in material slots a toggle button appears to repopulate the slots.  There are a couple of ways to make this automatic, but AFAIC are not worth the overhead.
The property Scene.materials will always return a set of all materials on all objects in scene.
bl_info = {
    &quot;name&quot;: &quot;Scene Materials&quot;,
    &quot;author&quot;: &quot;batFINGER&quot;,
    &quot;version&quot;: (1, 0),
    &quot;blender&quot;: (2, 80, 0),
    &quot;location&quot;: &quot;View3D &gt; UI &gt; Scene&quot;,
    &quot;description&quot;: &quot;List All Materials in Scene&quot;,
    &quot;warning&quot;: &quot;&quot;,
    &quot;doc_url&quot;: &quot;https://blender.stackexchange.com/a/141207/15543&quot;,
    &quot;category&quot;: &quot;Materials&quot;,
}

import bpy
from bpy.types import PropertyGroup
from bpy.props import (
    CollectionProperty,
    IntProperty,
    BoolProperty,
    StringProperty,
    PointerProperty,
)

def get_update_materials(self):

    update = set(s.material for s in self.material_slots).symmetric_difference(self.materials)
    if update:
        set_update_materials(self, True)
    return False


def set_update_materials(self, value):
    if value:
        self.material_slots.clear() # update (or get) instead?
        for m in self.materials:
            s = self.material_slots.add()
            s.name = m.name
            s.material = m


def get_scene_materials(self):
    return set(s.material for o in self.objects
               for s in o.material_slots if s.material)


class SceneMaterialSlot(PropertyGroup):
    def get_name(self):
        return getattr(self.material, &quot;name&quot;, &quot;&quot;)
    material: PointerProperty(type=bpy.types.Material)
    #name : StringProperty(get=get_name)


class MATERIAL_UL_extreme_matslot(bpy.types.UIList):

    def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
        ob = data
        slot = item
        ma = slot.material

        if self.layout_type in {'DEFAULT', 'COMPACT'}:
            if ma:
                layout.prop(ma, &quot;name&quot;, text=&quot;&quot;, emboss=False, icon_value=layout.icon(ma))


class SceneMaterialsPanel(bpy.types.Panel):

    bl_label = bl_info[&quot;name&quot;]
    bl_idname = &quot;SCENE_PT_materials&quot;
    bl_space_type = &quot;VIEW_3D&quot;
    bl_region_type = &quot;UI&quot;
    bl_category = &quot;Scene&quot;

    def draw(self, context):

        scn = context.scene
        layout = self.layout
        col = layout.column()
        if scn.update_materials:
            col.prop(scn, &quot;update_materials&quot;, toggle=True, icon='FILE_REFRESH')
        col.template_list(
            &quot;MATERIAL_UL_extreme_matslot&quot;,
            &quot;&quot;,
            scn,
            &quot;material_slots&quot;,
            scn,
            &quot;active_material_index&quot;)


classes = (SceneMaterialSlot,
           MATERIAL_UL_extreme_matslot,
           SceneMaterialsPanel)


def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.materials = property(get_scene_materials)
    bpy.types.Scene.update_materials = BoolProperty(
        get=get_update_materials,
        set=set_update_materials,
        name=&quot;Update Scene Materials&quot;)
    bpy.types.Scene.active_material_index = IntProperty()
    bpy.types.Scene.material_slots = CollectionProperty(
        type=SceneMaterialSlot)


def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)

    del bpy.types.Scene.active_material_index
    del bpy.types.Scene.material_slots


if __name__ == &quot;__main__&quot;:
    register()
        

Edit.
Updated code to make it installable as an addon. (Add a filters to show only materials of selected / visible / etc objects in scene)
Related:
Your layout code was nuffed, see @p2or's fabulous answer to
Create an interface which is similar to the material list box
Notes:
Not sure how would correlate scene material index vs active object material index. Rather than using the list UI a more basic UI, with labels

    for m in scn.materials:
        col.label(text=m.name, icon_value=layout.icon(m))

or with operators could be considered.