diff --git a/tools/README.md b/tools/README.md index bbbb5bc..5c0be8d 100644 --- a/tools/README.md +++ b/tools/README.md @@ -2,5 +2,6 @@ blob-patcher.py is a script for generating adrenotools loadable drivers from an extracted ROM zip qtimapper-shim allows newer drivers to work on devices that lack support for the new mapper HAL +acc-shim allows for suppling arguments to the underlying LLVM-based shader compiler library diff --git a/tools/acc-shim/README.md b/tools/acc-shim/README.md new file mode 100644 index 0000000..ac9d7f2 --- /dev/null +++ b/tools/acc-shim/README.md @@ -0,0 +1,12 @@ +## Adreno Compiler Collection parameter shim + +### TODO +Make some sort of API for this so parameters can be changed through adrenotools in realtime. + +### Compilation +``` +$ sed -i 's/libllvm-glnext/notreal-glnext/g' libllvm-glnext.so +$ mv libllvm-glnext.so notreal-glnext.so +$ aarch64-linux-android28-clang vk_acc_shim.cpp -o notllvm-glnext.so --shared -fpic +$ sed -i 's/libllvm-glnext/notllvm-glnext/g' vulkan.adreno.so +``` diff --git a/tools/acc-shim/vk_acc_shim.cpp b/tools/acc-shim/vk_acc_shim.cpp new file mode 100644 index 0000000..2bccb05 --- /dev/null +++ b/tools/acc-shim/vk_acc_shim.cpp @@ -0,0 +1,108 @@ +#include +#include +#include +#include + +thread_local int satisfy_driver_emutls; + +// Check libllvm-glnext.so in older drivers for a full list of these, newer ones are slightly more awkward due to the split +enum class OptionType : uint32_t { + ArgsStringList = 1, + QcArgsString = 4, + OptLevelInt = 0x101, + NoOptsInt = 0x10D, +}; + +struct StringListVal { + uint32_t len; + const char **entry; +}; + +struct Option +{ + OptionType type; + // PAD + union { + bool boolVal; + int intVal; + float floatVal; + StringListVal *strVals; + const char *strVal; + }; +}; + + +struct OptionsSet +{ + Option *options; + uint32_t num; +}; + + +int CompileHook(void *state, OptionsSet *opts); + +decltype(CompileHook) *OrigCompile{}; + +int CompileHook(void *state, OptionsSet *opts) { + constexpr size_t ReplacementOptsNum = 201; + + Option replacementOpts[ReplacementOptsNum]; + uint32_t patchedOptNum{}; + + // Insert your desired args here - results will be written to stderr + const char *argv[] = {"-help", "-help-hidden", "", NULL }; + StringListVal listVal{ + .len = 3, + .entry = argv, + }; + + replacementOpts[patchedOptNum++] = { + .type = OptionType::ArgsStringList, + .strVals = &listVal + }; + + const char *opt ="Verbose=true Quiet=false"; + replacementOpts[patchedOptNum++] = { + .type = OptionType::QcArgsString, + .strVal = opt + }; + + if (opts->num + patchedOptNum > ReplacementOptsNum) + __builtin_trap(); + + memcpy(&replacementOpts[patchedOptNum], opts->options, sizeof(Option) * opts->num); + + OptionsSet optList{ + .options = replacementOpts, + .num = opts->num + patchedOptNum + }; + + return OrigCompile(state, &optList); +} + + +struct LlvmInterface { + uint32_t unk0[3]; + // PAD + void *makeContext; + void *delContext; + decltype(CompileHook) *compile; + void *unk; +}; + +extern "C" int LoadACC(LlvmInterface *impl); + +extern "C" __attribute__((visibility("default"))) int LoadACC(LlvmInterface *impl) { + void *hnd = dlopen("notreal-glnext.so", RTLD_NOW); + + auto origLoadACC = reinterpret_cast(dlsym(hnd, "LoadACC")); + if (!origLoadACC) + __builtin_trap(); + + int ret = origLoadACC(impl); + + OrigCompile = impl->compile; + impl->compile = &CompileHook; + + return ret; +}