summaryrefslogtreecommitdiffstats
path: root/source/core/slang-shared-library.cpp
blob: fd61ba0a0e1c5abd40bfc2e1c67064b75e049bcc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "slang-shared-library.h"

#include "../../slang-com-ptr.h"

#include "slang-io.h"
#include "slang-string-util.h"

namespace Slang
{

// Allocate static const storage for the various interface IDs that the Slang API needs to expose
static const Guid IID_ISlangUnknown = SLANG_UUID_ISlangUnknown;
static const Guid IID_ISlangSharedLibrary = SLANG_UUID_ISlangSharedLibrary;
static const Guid IID_ISlangSharedLibraryLoader = SLANG_UUID_ISlangSharedLibraryLoader;

/* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibraryLoader !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/

/* static */const char* DefaultSharedLibraryLoader::s_libraryNames[int(SharedLibraryType::CountOf)] =
{
    nullptr,                    // SharedLibraryType::Unknown 
    "dxcompiler",               // SharedLibraryType::Dxc 
    "d3dcompiler_47",           // SharedLibraryType::Fxc
    "slang-glslang",            // SharedLibraryType::Glslang  
    "dxil",                     // SharedLibraryType::Dxil
};

/* static */DefaultSharedLibraryLoader DefaultSharedLibraryLoader::s_singleton;

/* static */SharedLibraryType DefaultSharedLibraryLoader::getSharedLibraryTypeFromName(const UnownedStringSlice& name)
{
    // Start from 1 to skip Unknown
    for (int i = 1; i < SLANG_COUNT_OF(s_libraryNames); ++i)
    {
        if (name == s_libraryNames[i])
        {
            return SharedLibraryType(i);
        }
    }
    return SharedLibraryType::Unknown;
}

ISlangUnknown* DefaultSharedLibraryLoader::getInterface(const Guid& guid)
{
    return (guid == IID_ISlangUnknown || guid == IID_ISlangSharedLibraryLoader) ? static_cast<ISlangSharedLibraryLoader*>(this) : nullptr;
}

SlangResult DefaultSharedLibraryLoader::loadSharedLibrary(const char* path, ISlangSharedLibrary** sharedLibraryOut)
{
    *sharedLibraryOut = nullptr;
    // Try loading
    SharedLibrary::Handle handle;
    SLANG_RETURN_ON_FAIL(SharedLibrary::load(path, handle));
    *sharedLibraryOut = ComPtr<ISlangSharedLibrary>(new DefaultSharedLibrary(handle)).detach();
    return SLANG_OK;
}

/* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/

TemporarySharedLibrary::~TemporarySharedLibrary()
{
    if (m_sharedLibraryHandle)
    {
        // We have to unload if we want to be able to remove
        SharedLibrary::unload(m_sharedLibraryHandle);
        m_sharedLibraryHandle = nullptr;
    }
}

/* !!!!!!!!!!!!!!!!!!!!!!!!!! DefaultSharedLibrary !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/

ISlangUnknown* DefaultSharedLibrary::getInterface(const Guid& guid)
{
    return (guid == IID_ISlangUnknown || guid == IID_ISlangSharedLibrary) ? static_cast<ISlangSharedLibrary*>(this) : nullptr;
}

DefaultSharedLibrary::~DefaultSharedLibrary()
{
    if (m_sharedLibraryHandle)
    {
        SharedLibrary::unload(m_sharedLibraryHandle);
    }
}

SlangFuncPtr DefaultSharedLibrary::findFuncByName(char const* name)
{
    return SharedLibrary::findFuncByName(m_sharedLibraryHandle, name); 
}

/* !!!!!!!!!!!!!!!!!!!!!!!!!! ConfigurableSharedLibraryLoader !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/

ISlangUnknown* ConfigurableSharedLibraryLoader::getInterface(const Guid& guid)
{
    return (guid == IID_ISlangUnknown || guid == IID_ISlangSharedLibraryLoader) ? static_cast<ISlangSharedLibraryLoader*>(this) : nullptr;
}

SlangResult ConfigurableSharedLibraryLoader::loadSharedLibrary(const char* path, ISlangSharedLibrary** sharedLibraryOut)
{
    Entry* entry = m_entryMap.TryGetValue(String(path));
    if (entry)
    {
        SharedLibrary::Handle handle;
        SLANG_RETURN_ON_FAIL(entry->func(path, entry->entryString, handle));
        SLANG_ASSERT(handle);

        ComPtr<ISlangSharedLibrary> sharedLib(new DefaultSharedLibrary(handle));
        *sharedLibraryOut = sharedLib.detach();
        return SLANG_OK;
    }

    return DefaultSharedLibraryLoader::getSingleton()->loadSharedLibrary(path, sharedLibraryOut);
}

/* static */Result ConfigurableSharedLibraryLoader::replace(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut)
{
    SLANG_UNUSED(pathIn);
    // The replacement is the *whole* string
    return SharedLibrary::loadWithPlatformPath(entryString.begin(), handleOut);
}

/* static */Result ConfigurableSharedLibraryLoader::changePath(const char* pathIn, const String& entryString, SharedLibrary::Handle& handleOut )
{
    // Okay we need to reconstruct the name and insert the path
    StringBuilder builder;
    SharedLibrary::appendPlatformFileName(UnownedStringSlice(pathIn), builder);
    String path = Path::combine(entryString, builder);

    return SharedLibrary::loadWithPlatformPath(path.begin(), handleOut);
}


}