Вызов FSR `ffxQuery` из кода C# для определения поддержки DLL.C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Вызов FSR `ffxQuery` из кода C# для определения поддержки DLL.

Сообщение Anonymous »

Для некоторых проектов, над которыми я работаю, я пытаюсь загрузить библиотеки DLL FSR 3.1 и прочитать, какая у них версия. В некоторых dll версия указана в свойствах файла. Например, DLSS 3.7 будет иметь свою DLL с версией файла 3.7.0.0. В FSR 3.1 они скомпилировали свои библиотеки DLL так, что версия файла — 1.0.1.39157, версия продукта — 1.0.1.0, но версия FSR, которая, как я знаю, находится внутри, — 3.1.3.
Я у нас есть репозиторий, над которым ведется работа.
Проблема
При случайном FSR (например. amd_fidelityfx_dx12.dll), загрузите его в приложение C# и вызовите метод ffxQuery.
Библиотеки DLL можно получить либо при запуске кода из вышеуказанного репозитория, либо они также включены в SDK AMD FidelityFX.
Упомянутый выше ffqQuery взят из образцов, предоставленных AMD здесь и здесь. Однако этот код написан на C++, мне нужно сделать то же самое, что и на C#.
Моя текущая попытка
Моя текущая попытка попытка находится в моем репозитории ReadFSRVersionFromCSharp. Сначала я не мог ничего загрузить. Немного поспав и с помощью GitHub Copilot/GPT-4o выдал код, который наполовину работает.
Я не C++-разработчик, у меня нет знаний по правильной загрузке C++-dll. в С#. Если ИИ дал мне ужасный код, укажите, как я могу его улучшить.
В файле AMDFidelityFXAPI.cs мне удалось заставить его динамически загружать DLL. используя методы из kernel32.dll

Код: Выделить всё

    // Define the LoadLibrary and GetProcAddress functions
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LoadLibrary(string lpFileName);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeLibrary(IntPtr hModule);
Первая половина приведенных примеров кода C++ выглядит следующим образом:

Код: Выделить всё

ffx::QueryDescGetVersions versionQuery{};
versionQuery.createDescType = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;
versionQuery.device = GetDX12Device(); // only for DirectX 12 applications
uint64_t versionCount = 0;
versionQuery.outputCount = &versionCount;
// get number of versions for allocation
ffxQuery(nullptr, &versionQuery.header);
Мне удалось заставить это работать на C# вот так,

Код: Выделить всё

var versionQuery = new QueryDescGetVersions();

//versionQuery.createDescType = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;
versionQuery.createDescType = FxxConsts.FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;

// versionQuery.device = GetDX12Device(); // only for DirectX 12 applications
versionQuery.device = IntPtr.Zero;

// uint64_t versionCount = 0;
UInt64 versionCount = 0;
versionQuery.outputCount = Marshal.AllocHGlobal(sizeof(UInt64));
Marshal.WriteInt64(versionQuery.outputCount, (UInt32)versionCount);

Debug.WriteLine("AMDFidelityFXAPI - Reading version count");
// get number of versions for allocation
// ffxQuery(IntPtr.Zero, &versionQuery.header);
var returnCode = ffxQuery(IntPtr.Zero, ref versionQuery);
Debug.WriteLine($"AMDFidelityFXAPI - returnCode: {returnCode}");

versionCount = (UInt64)Marshal.ReadInt64(versionQuery.outputCount);
Debug.WriteLine($"AMDFidelityFXAPI - versionCount: {versionCount}");
Теперь у него есть versionCount, содержащий значение 2. Насколько мне известно, это ожидаемо, поскольку FSR 3.1.x также содержит FSR 2.3.y в качестве запасного варианта.
Оставшаяся проблемаВторая половина кода, предоставленного AMD, должна загрузить версию и идентификаторы FSR.

Код: Выделить всё

std::vector versionNames;
std::vector versionIds;
m_FsrVersionIds.resize(versionCount);
versionNames.resize(versionCount);
versionQuery.versionIds = versionIds.data();
versionQuery.versionNames = versionNames.data();
// fill version ids and names arrays.
ffxQuery(nullptr, &versionQuery.header);
Затем был создан код C#, который выглядит следующим образом (опять же, если это неправильно или может быть улучшено, дайте мне знать)

Код: Выделить всё

var versionCountInt = (int)versionCount;

//std::vector  versionNames;
//std::vector versionIds;
//m_FsrVersionIds.resize(versionCount);
//versionNames.resize(versionCount);
var versionNames = new List(versionCountInt);
var versionIds = new List(versionCountInt);

var versionNamesPtrs = new IntPtr[versionCountInt];
var versionIdsPtrs = new IntPtr[versionCountInt];

try
{
for (var i = 0; i < versionCountInt; i++)
{
versionNames.Add(null);
versionIds.Add(0);
}

//versionQuery.versionIds = versionIds.data();
//versionQuery.versionNames = versionNames.data();

versionQuery.versionIds = Marshal.AllocHGlobal(sizeof(UInt64) * versionCountInt);
versionQuery.versionNames = Marshal.AllocHGlobal(IntPtr.Size * versionCountInt);

for (var i = 0; i < versionCountInt; i++)
{
versionIdsPtrs[i] = Marshal.AllocHGlobal(sizeof(UInt64));
Marshal.WriteInt64(versionIdsPtrs[i], (long)versionIds[i]);
Marshal.WriteIntPtr(versionQuery.versionIds, i * IntPtr.Size, versionIdsPtrs[i]);

versionNamesPtrs[i] = Marshal.StringToHGlobalAnsi(versionNames[i]);
Marshal.WriteIntPtr(versionQuery.versionNames, i * IntPtr.Size, versionNamesPtrs[i]);
}

// fill version ids and names arrays.
//ffxQuery(nullptr, &versionQuery.header);
returnCode = ffxQuery(IntPtr.Zero, ref versionQuery);
Debug.WriteLine($"AMDFidelityFXAPI - returnCode: {returnCode}");

if (returnCode != FfxApiReturnCodes.FFX_API_RETURN_OK)
{
throw new Exception($"Failed to get version count.  Return code: {returnCode}");
}

for (var i = 0; i < versionCountInt; i++)
{
versionIds[i] = (UInt64)Marshal.ReadInt64(versionIdsPtrs[i]);
versionNames[i] = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(versionQuery.versionNames, i * IntPtr.Size));
}

Console.WriteLine("AMDFidelityFXAPI - Version Names and IDs:");

for (var i = 0; i < versionCountInt; i++)
{
Console.WriteLine($"ID: {versionIds[i]}, Name: {versionNames[i]}");
}

return versionNames;
}
finally
{
foreach (var ptr in versionIdsPtrs)
{
Marshal.FreeHGlobal(ptr);
}
foreach (var ptr in versionNamesPtrs)
{
Marshal.FreeHGlobal(ptr);
}
Marshal.FreeHGlobal(versionQuery.versionIds);
Marshal.FreeHGlobal(versionQuery.versionNames);
}
Проблема в том, что выходные данные Console.WriteLine($"ID: {versionIds}, Name: {versionNames}"); кажутся не сообщает правильно.
Если я запущу это как в библиотеках DX12, так и в Vulkan, я получу следующий результат:

Код: Выделить всё

AMDFidelityFXAPI - Loading amd_fidelityfx_vk.dll
AMDFidelityFXAPI - Reading version count
AMDFidelityFXAPI - returnCode: FFX_API_RETURN_OK
AMDFidelityFXAPI - versionCount: 2
AMDFidelityFXAPI - returnCode: FFX_API_RETURN_OK
AMDFidelityFXAPI - Version Names and IDs:
ID: 0, Name: 3.1.3
ID: 0, Name: 2.3.2

AMDFidelityFXAPI - Loading amd_fidelityfx_dx12.dll
AMDFidelityFXAPI - Reading version count
AMDFidelityFXAPI - returnCode: FFX_API_RETURN_OK
AMDFidelityFXAPI - versionCount: 2
AMDFidelityFXAPI - returnCode: FFX_API_RETURN_OK
AMDFidelityFXAPI - Version Names and IDs:
ID: 0, Name: 3.1.3
ID: 0, Name: 2.3.2
Если я изменю строку versionIds.Add(0); на versionIds.Add(7);, то мой вывод будет выглядеть так:

Код: Выделить всё

ID: 7, Name: 3.1.3
Я считаю, что что-то не так с приведенным выше кодом в его настройке перед вызовом ffxQuery, но я не могу быть уверен на 100%. В документах AMD, ссылка на которые приведена выше, говорится:

Используйте только идентификаторы версий, возвращаемые ffxQuery, в ffxQueryDescGetVersions с соответствующим типом структуры создания

из этого я предполагаю, что идентификаторы, возвращаемые для строк 3.1.3 и 2.3.2, должны отличаться, поскольку они используются при создании контекста FSR относительно того, какую версию использовать.

Подробнее здесь: https://stackoverflow.com/questions/793 ... ll-support
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Вызов FSR `ffxQuery` из кода C# для определения поддержки DLL.
    Anonymous » » в форуме C++
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • Загрузка dll FSR 3.1 на C# для загрузки версий не загружает идентификаторы версий
    Anonymous » » в форуме C#
    0 Ответы
    27 Просмотры
    Последнее сообщение Anonymous
  • Загрузка dll FSR 3.1 на C# для загрузки версий не загружает идентификаторы версий
    Anonymous » » в форуме C++
    0 Ответы
    20 Просмотры
    Последнее сообщение Anonymous
  • Поле Azure Document Intelligence C# SDK поддержки поддержки?
    Anonymous » » в форуме C#
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous
  • Java Рассмотрите возможность определения bean-компонента типа в исключении конфигурации при добавлении поддержки mongoDB
    Anonymous » » в форуме JAVA
    0 Ответы
    89 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»