Sync3DReceive
Demonstrates how to receive notifications of changes in 3D settings using ADLX. To receive the event, another application must be used to change these settings, such as the AntiLag.
Sample Path
/Samples/CPP/ReceivingEventsNotifications/Sync3DReceive
Code
//
// Copyright (c) 2021 - 2024 Advanced Micro Devices, Inc. All rights reserved.
//
//-------------------------------------------------------------------------------------------------
#include "SDK/ADLXHelper/Windows/Cpp/ADLXHelper.h"
#include "SDK/Include/I3DSettings.h"
#include "SDK/Include/I3DSettings1.h"
#include "conio.h"
#include <iostream>
#include <string>
#include <map>
#include <thread>
// Use ADLX namespace.
using namespace adlx;
// ADLXHelper instance.
// No outstanding interfaces from ADLX must exist when ADLX is destroyed.
// Use global variables to ensure validity of the interface.
static ADLXHelper g_ADLXHelp;
// Block event to verify call back.
HANDLE blockEvent = nullptr;
HANDLE quitEvent = nullptr;
// AnisotropicFiltering level map
static const std::map<ADLX_ANISOTROPIC_FILTERING_LEVEL, const char*> levelMap =
{
{AF_LEVEL_INVALID , "Invalid"},
{AF_LEVEL_X2 , "2X"},
{AF_LEVEL_X4 , "4X"},
{AF_LEVEL_X8 , "8X"},
{AF_LEVEL_X16 , "16X"} };
// WaitForVerticalRefresh mode
static const std::map<ADLX_WAIT_FOR_VERTICAL_REFRESH_MODE, const char*> vsyncMode =
{
{WFVR_ALWAYS_OFF , "Always off"},
{WFVR_OFF_UNLESS_APP_SPECIFIES , "Off, unless application specifies"},
{WFVR_ON_UNLESS_APP_SPECIFIES , "On, unless application specifies"},
{WFVR_ALWAYS_ON , "Always on"} };
// antiAliasing mode
static const std::map<ADLX_ANTI_ALIASING_MODE, const char*> antiAliasingMode =
{
{AA_MODE_USE_APP_SETTINGS , "Use application settings"},
{AA_MODE_ENHANCE_APP_SETTINGS , "Enhance application settings"},
{AA_MODE_OVERRIDE_APP_SETTINGS , "Override application settings"} };
// antiAliasing method
static const std::map<ADLX_ANTI_ALIASING_METHOD, const char*> antiAliasingMethod =
{
{AA_METHOD_MULTISAMPLING , "Muti-Sampling"},
{AA_METHOD_ADAPTIVE_MULTISAMPLING , "Adaptive Muti-Sampling"},
{AA_METHOD_SUPERSAMPLING , "Super Sampling"} };
// antiAliasing level
static const std::map<ADLX_ANTI_ALIASING_LEVEL, const char*> antiAliasingLevel =
{
{AA_LEVEL_INVALID , "Level Invalid"},
{AA_LEVEL_2X , "2X"},
{AA_LEVEL_2XEQ , "2XEQ"},
{AA_LEVEL_4X , "4X"},
{AA_LEVEL_4XEQ , "4XEQ"},
{AA_LEVEL_8X , "8X"},
{AA_LEVEL_8XEQ , "8XEQ"} };
// TessellationMode mode
static const std::map<ADLX_TESSELLATION_MODE, const char*> Modes =
{
{T_MODE_AMD_OPTIMIZED , "AMD optimized"},
{T_MODE_USE_APP_SETTINGS , "Use application settings"},
{T_MODE_OVERRIDE_APP_SETTINGS , "Override application settings"} };
// TessellationMode level
static const std::map<ADLX_TESSELLATION_LEVEL, const char*> Levels =
{
{T_LEVEL_OFF , "Off"},
{T_LEVEL_2X , "2X"},
{T_LEVEL_4X , "4X"},
{T_LEVEL_6X , "6X"},
{T_LEVEL_8X , "8X"},
{T_LEVEL_16X , "16X"},
{T_LEVEL_32X , "32X"},
{T_LEVEL_64X , "64X"} };
// Get the GPU unique name
void GPUUniqueName(IADLXGPUPtr gpu, char* uniqueName);
// Call back to handl changed events
class CallBack3DSettingsChanged : public IADLX3DSettingsChangedListener
{
public:
adlx_bool ADLX_STD_CALL On3DSettingsChanged(IADLX3DSettingsChangedEvent* p3DSettingsChangedEvent) override
{
// Get 3DSettings service
IADLX3DSettingsServicesPtr d3dSettingSrv;
g_ADLXHelp.GetSystemServices()->Get3DSettingsServices(&d3dSettingSrv);
IADLX3DSettingsServices1Ptr d3dSettingSrv1 (d3dSettingSrv);
IADLX3DSettingsChangedEvent1Ptr p3DSettingsChangedEvent1(p3DSettingsChangedEvent);
if (p3DSettingsChangedEvent1 == nullptr)
{
std::cout << "3DSettingsChangedEvent1 not supported" << std::endl;
}
// Get the GPU interface
IADLXGPUPtr gpu;
p3DSettingsChangedEvent->GetGPU(&gpu);
//RadeonSuperResolution is a global feature (the GPU interface is nullptr); skip printing its name
if (!p3DSettingsChangedEvent->IsRadeonSuperResolutionChanged())
{
char uniqueName[128] = "Unknown";
GPUUniqueName(gpu, uniqueName);
std::cout << "GPU: " << uniqueName << ", Get sync event, 3D settings changed event was fired" << std::endl;
}
ADLX_SYNC_ORIGIN origin = p3DSettingsChangedEvent->GetOrigin();
if (origin == SYNC_ORIGIN_EXTERNAL )
{
if (p3DSettingsChangedEvent->IsAntiLagChanged())
{
// Get AntiLag interface
IADLX3DAntiLagPtr d3dAntiLag;
d3dSettingSrv->GetAntiLag(gpu, &d3dAntiLag);
adlx_bool enabled;
d3dAntiLag->IsEnabled(&enabled);
std::cout <<"\\tAntiLag changed\\n\\tIsEnabled: " << enabled << std::endl;
}
else if (p3DSettingsChangedEvent->IsChillChanged())
{
// Get Chill interface
IADLX3DChillPtr d3dChill;
d3dSettingSrv->GetChill(gpu, &d3dChill);
adlx_bool enabled;
d3dChill->IsEnabled(&enabled);
adlx_int minFPS, maxFPS;
d3dChill->GetMinFPS(&minFPS);
d3dChill->GetMaxFPS(&maxFPS);
std::cout << "\\tChill changed\\n\\tIsEnabled: " << enabled << " , FPS: [ " << minFPS << " , " << maxFPS << " ]" << std::endl;
}
else if (p3DSettingsChangedEvent->IsBoostChanged())
{
// Get Boost interface
IADLX3DBoostPtr d3dBoost;
d3dSettingSrv->GetBoost(gpu, &d3dBoost);
adlx_bool enabled;
d3dBoost->IsEnabled(&enabled);
adlx_int minRes;
d3dBoost->GetResolution(&minRes);
std::cout << "\\tBoost changed\\n\\tIsEnabled: " << enabled << " , minResolution: " << minRes << std::endl;
}
else if (p3DSettingsChangedEvent->IsImageSharpeningChanged())
{
// Get ImageSharpen interface
IADLX3DImageSharpeningPtr d3dImageSharpen;
d3dSettingSrv->GetImageSharpening(gpu, &d3dImageSharpen);
adlx_bool enabled;
d3dImageSharpen->IsEnabled(&enabled);
adlx_int min;
d3dImageSharpen->GetSharpness(&min);
std::cout << "\\tImageSharpening changed\\n\\tIsEnabled: " << enabled << " , Sharpness: " << min << std::endl;
}
else if (p3DSettingsChangedEvent->IsEnhancedSyncChanged())
{
// Get EnhancedSync interface
IADLX3DEnhancedSyncPtr d3dEnhancedSync;
d3dSettingSrv->GetEnhancedSync(gpu, &d3dEnhancedSync);
adlx_bool enabled;
d3dEnhancedSync->IsEnabled(&enabled);
std::cout << "\\tEnhancedSync changed\\n\\tIsEnabled: " << enabled << std::endl;
}
else if (p3DSettingsChangedEvent->IsWaitForVerticalRefreshChanged())
{
// Get Vsync interface
IADLX3DWaitForVerticalRefreshPtr vsync;
d3dSettingSrv->GetWaitForVerticalRefresh(gpu, &vsync);
adlx_bool enabled;
vsync->IsEnabled(&enabled);
ADLX_WAIT_FOR_VERTICAL_REFRESH_MODE mode = WFVR_ALWAYS_OFF ;
vsync->GetMode(&mode);
std::cout << "\\tWaitForVerticalRefresh changed\\n\\tIsEnabled: " << enabled << " , Mode: " << vsyncMode.find(mode)->second << std::endl;
}
else if (p3DSettingsChangedEvent->IsFrameRateTargetControlChanged())
{
// Get FRTC interface
IADLX3DFrameRateTargetControlPtr frtc;
d3dSettingSrv->GetFrameRateTargetControl(gpu, &frtc);
adlx_bool enabled;
frtc->IsEnabled(&enabled);
adlx_int fps;
frtc->GetFPS(&fps);
std::cout << "\\tFRTC changed\\n\\tIsEnabled: " << enabled << " , fps: " << fps << std::endl;
}
else if (p3DSettingsChangedEvent->IsAntiAliasingChanged())
{
// Get AntiAliasing interface
IADLX3DAntiAliasingPtr antiAliasing;
d3dSettingSrv->GetAntiAliasing(gpu, &antiAliasing);
ADLX_ANTI_ALIASING_MODE mode;
antiAliasing->GetMode(&mode);
ADLX_ANTI_ALIASING_METHOD method;
antiAliasing->GetMethod(&method);
ADLX_ANTI_ALIASING_LEVEL level;
antiAliasing->GetLevel(&level);
std::cout << "\\tAntiAliasing changed\\n" << std::endl
<< "\\tMode: " << antiAliasingMode.find(mode)->second << std::endl
<< "\\tMethod: " << antiAliasingMethod.find(method)->second << std::endl
<< "\\tLevel: " << antiAliasingLevel.find(level)->second << std::endl;
}
else if (p3DSettingsChangedEvent->IsMorphologicalAntiAliasingChanged())
{
// Get MorphologicAntiAliasing interface
IADLX3DMorphologicalAntiAliasingPtr mAntiAliasing;
d3dSettingSrv->GetMorphologicalAntiAliasing(gpu, &mAntiAliasing);
adlx_bool enabled;
mAntiAliasing->IsEnabled(&enabled);
std::cout << "\\tMorphologicalAntiAliasing changed\\n\\tIsEnabled: " << enabled << std::endl;
}
else if (p3DSettingsChangedEvent->IsAnisotropicFilteringChanged())
{
// Get AnisotropicFilteringPtr interface
IADLX3DAnisotropicFilteringPtr anisotropicFiltering;
d3dSettingSrv->GetAnisotropicFiltering(gpu, &anisotropicFiltering);
adlx_bool enabled;
anisotropicFiltering->IsEnabled(&enabled);
ADLX_ANISOTROPIC_FILTERING_LEVEL level;
anisotropicFiltering->GetLevel(&level);
std::cout << "\\tAnisotropicFiltering changed\\n\\tIsEnabled: " << enabled << std::endl
<< "\\tLevel: " << levelMap.find(level)->second << std::endl;
}
else if (p3DSettingsChangedEvent->IsTessellationModeChanged())
{
// Get IADLX3DTessellation interface
IADLX3DTessellationPtr tessellation;
d3dSettingSrv->GetTessellation(gpu, &tessellation);
ADLX_TESSELLATION_MODE mode;
tessellation->GetMode(&mode);
ADLX_TESSELLATION_LEVEL level;
tessellation->GetLevel(&level);
std::cout << "\\tTessellationMode changed\\n" << std::endl
<< "\\tMode: " << Modes.find(mode)->second << std::endl
<< "\\tLevel: " << Levels.find(level)->second << std::endl;
}
else if (p3DSettingsChangedEvent->IsResetShaderCache())
{
std::cout << "\\tResetShaderCache" << std::endl;
}
}
if (origin == SYNC_ORIGIN_UNKNOWN )
{
if (p3DSettingsChangedEvent->IsRadeonSuperResolutionChanged())
{
// Get IADLX3DRadeonSuperResolution interface
IADLX3DRadeonSuperResolutionPtr rsr;
d3dSettingSrv->GetRadeonSuperResolution(&rsr);
adlx_bool enabled = false;
rsr->IsEnabled(&enabled);
adlx_int sharpness;
rsr->GetSharpness(&sharpness);
std::cout << "\\tRSR changed\\n\\tIsEnabled: " << enabled << " , Sharpness: " << sharpness << std::endl;
}
else if (p3DSettingsChangedEvent1->IsAMDFluidMotionFramesChanged())
{
// Get AMDFluidMotionFrames interface
IADLX3DAMDFluidMotionFramesPtr d3dAfmd;
d3dSettingSrv1->GetAMDFluidMotionFrames(&d3dAfmd);
adlx_bool enabled;
d3dAfmd->IsEnabled(&enabled);
std::cout << "\\tAMDFluidMotionFrmes changed\\n\\tIsEnabled: " << enabled << std::endl;
}
}
SetEvent(blockEvent);
// Return true for ADLX to continue notifying the next listener, or false to stop notification
return true;
}
};
// Wait for quit signal
void QuitWait(adlx_bool* loopFlag)
{
while (true)
{
// Non-blocking checking if the I/O cache has characters
if (_kbhit())
{
char c;
if ((c = getchar()) == 'q' || c == 'Q')
{
*loopFlag = false;
SetEvent(quitEvent);
break;
}
}
Sleep(100);
}
}
int main()
{
// Define return code
ADLX_RESULT res = ADLX_FAIL ;
// Initialize ADLX
res = g_ADLXHelp.Initialize();
if (ADLX_SUCCEEDED (res))
{
// Create block event
blockEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// Create quit event
quitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// Create event array
HANDLE eventArray[] = { blockEvent, quitEvent };
// Get 3DSettings service
IADLX3DSettingsServicesPtr d3dSettingSrv;
res = g_ADLXHelp.GetSystemServices()->Get3DSettingsServices(&d3dSettingSrv);
if (ADLX_SUCCEEDED (res))
{
// Get Change handle
IADLX3DSettingsChangedHandlingPtr changeHandle;
res = d3dSettingSrv->Get3DSettingsChangedHandling(&changeHandle);
if (ADLX_SUCCEEDED (res))
{
// Create call back
IADLX3DSettingsChangedListener* call = new CallBack3DSettingsChanged;
// Add call back
changeHandle->Add3DSettingsEventListener(call);
// Create a thread to check quit event
bool loopFlag = true;
std::thread t{ QuitWait, &loopFlag};
std::cout << "\\nWaiting for 3DSetting change event... Press Q/q to quit" << std::endl;
while (true)
{
// Wait for change event or request to quit
DWORD waitRet = WaitForMultipleObjects(2, eventArray, FALSE, INFINITE);
if (!loopFlag)
{
if (t.joinable())
{
t.join();
}
break;
}
ResetEvent(blockEvent);
}
// Remove call back
changeHandle->Remove3DSettingsEventListener(call);
// Delete call back
delete call;
call = nullptr;
}
}
else
{
std::cout << "Failed to get the 3DSettings Services" << std::endl;
}
}
else
{
std::cout << "ADLX initialization failed" << std::endl;
return 0;
}
// Destroy ADLX
res = g_ADLXHelp.Terminate();
std::cout << "Destroy ADLX res: " << res << std::endl;
// Close event
if (blockEvent)
CloseHandle(blockEvent);
if (quitEvent)
CloseHandle(quitEvent);
// Pause to see the print out
system("pause");
return 0;
}
void GPUUniqueName(IADLXGPUPtr gpu, char* uniqueName)
{
if (nullptr != gpu && nullptr != uniqueName)
{
const char* gpuName = nullptr;
gpu->Name(&gpuName);
adlx_int id;
gpu->UniqueId(&id);
sprintf_s(uniqueName, 128, "name:%s, id:%d", gpuName, id);
}
}