mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-25 13:31:15 +00:00
added r_gpuIndex and /gpulist
This commit is contained in:
parent
0cae0a9545
commit
9a66155d14
7 changed files with 155 additions and 2 deletions
|
@ -37,6 +37,12 @@ add: r_gpuPreference <0 to 2> (default: 0) sets the GPU selection preference
|
|||
1 - low power (integrated graphics)
|
||||
2 - none
|
||||
|
||||
add: r_gpuIndex <0 to GPU count> (default: 0) sets the specific GPU to use
|
||||
0 - default (falls back to r_gpuPreference)
|
||||
I - uses the GPU at index I from /gpulist
|
||||
|
||||
add: /gpulist lists available GPUs, the numbers can be used to set r_gpuIndex
|
||||
|
||||
add: r_sleepThreshold <2000 to 4000> (default: 2500) is the frame sleep time cushion, in microseconds
|
||||
it's a trade-off between frame time consistency and CPU usage
|
||||
set to 2000 if you have a struggling old/low-power CPU
|
||||
|
|
|
@ -634,6 +634,12 @@ namespace RHI
|
|||
ResourceStates::Flags newState = ResourceStates::Common;
|
||||
};
|
||||
|
||||
struct GPU
|
||||
{
|
||||
char name[256];
|
||||
LUID uniqueId;
|
||||
};
|
||||
|
||||
struct RHIPrivate
|
||||
{
|
||||
bool initialized;
|
||||
|
@ -733,6 +739,8 @@ namespace RHI
|
|||
PIX pix;
|
||||
int64_t beforeInputSamplingUS;
|
||||
int64_t beforeRenderingUS;
|
||||
GPU gpus[16];
|
||||
uint32_t gpuCount;
|
||||
|
||||
// immediate-mode barrier API
|
||||
TextureBarrier textureBarriers[64];
|
||||
|
@ -1453,6 +1461,52 @@ namespace RHI
|
|||
return true;
|
||||
}
|
||||
|
||||
static void CreateAdapterList()
|
||||
{
|
||||
IDXGIAdapter1* adapter = NULL;
|
||||
UINT enumIndex = 0;
|
||||
rhi.gpuCount = 0;
|
||||
while(rhi.gpuCount < ARRAY_LEN(rhi.gpus) &&
|
||||
SUCCEEDED(rhi.factory->EnumAdapters1(enumIndex++, &adapter)))
|
||||
{
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
if(IsSuitableAdapter(adapter) && SUCCEEDED(adapter->GetDesc1(&desc)))
|
||||
{
|
||||
GPU& gpu = rhi.gpus[rhi.gpuCount++];
|
||||
gpu.uniqueId = desc.AdapterLuid;
|
||||
Q_strncpyz(gpu.name, GetUTF8String(desc.Description, "???"), sizeof(gpu.name));
|
||||
}
|
||||
COM_RELEASE(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
static IDXGIAdapter1* GetAdapterAtIndex(int gpuIndex)
|
||||
{
|
||||
if(gpuIndex < 0 || gpuIndex >= ARRAY_LEN(rhi.gpus))
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "GPU index %d is invalid", gpuIndex + 1);
|
||||
return NULL;
|
||||
}
|
||||
const LUID uniqueId = rhi.gpus[gpuIndex].uniqueId;
|
||||
|
||||
IDXGIAdapter1* adapter = NULL;
|
||||
UINT enumIndex = 0;
|
||||
while(SUCCEEDED(rhi.factory->EnumAdapters1(enumIndex++, &adapter)))
|
||||
{
|
||||
DXGI_ADAPTER_DESC1 desc;
|
||||
if(SUCCEEDED(adapter->GetDesc1(&desc)) &&
|
||||
desc.AdapterLuid.LowPart == uniqueId.LowPart &&
|
||||
desc.AdapterLuid.HighPart == uniqueId.HighPart)
|
||||
{
|
||||
return adapter;
|
||||
}
|
||||
COM_RELEASE(adapter);
|
||||
}
|
||||
|
||||
ri.Printf(PRINT_WARNING, "GPU at index %d (%s) is no longer available", gpuIndex + 1, rhi.gpus[gpuIndex].name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static IDXGIAdapter1* FindMostSuitableAdapter(IDXGIFactory1* factory, int enginePreference)
|
||||
{
|
||||
IDXGIAdapter1* adapter = NULL;
|
||||
|
@ -3145,7 +3199,15 @@ namespace RHI
|
|||
D3D(CreateDXGIFactory1(IID_PPV_ARGS(&rhi.factory)));
|
||||
#endif
|
||||
|
||||
rhi.adapter = FindMostSuitableAdapter(rhi.factory, r_gpuPreference->integer);
|
||||
CreateAdapterList();
|
||||
if(r_gpuIndex->integer > 0)
|
||||
{
|
||||
rhi.adapter = GetAdapterAtIndex(r_gpuIndex->integer - 1);
|
||||
}
|
||||
if(rhi.adapter == NULL)
|
||||
{
|
||||
rhi.adapter = FindMostSuitableAdapter(rhi.factory, r_gpuPreference->integer);
|
||||
}
|
||||
{
|
||||
char adapterName[256];
|
||||
const char* adapterNamePtr = "unknown";
|
||||
|
@ -3158,6 +3220,24 @@ namespace RHI
|
|||
ri.Printf(PRINT_ALL, "Selected graphics adapter: %s\n", adapterNamePtr);
|
||||
Q_strncpyz(rhi.adapterName, adapterNamePtr, sizeof(rhi.adapterName));
|
||||
}
|
||||
{
|
||||
Cvar_SetRange(r_gpuIndex->name, r_gpuIndex->type, "0", va("%d", rhi.gpuCount));
|
||||
|
||||
char values[256];
|
||||
StringList stringList;
|
||||
stringList.Init(values, sizeof(values));
|
||||
stringList.Append("0");
|
||||
stringList.Append("Default GPU");
|
||||
stringList.Append("");
|
||||
for(uint32_t i = 0; i < rhi.gpuCount; ++i)
|
||||
{
|
||||
stringList.Append(va("%d", (int)i + 1));
|
||||
stringList.Append(rhi.gpus[i].name);
|
||||
stringList.Append("");
|
||||
}
|
||||
stringList.Terminate();
|
||||
Cvar_SetMenuData(r_gpuIndex->name, CVARCAT_DISPLAY | CVARCAT_PERFORMANCE, "GPU selection", "Choose the GPU to use", "", values);
|
||||
}
|
||||
|
||||
D3D(D3D12CreateDevice(rhi.adapter, FeatureLevel, IID_PPV_ARGS(&rhi.device)));
|
||||
|
||||
|
@ -3475,6 +3555,13 @@ namespace RHI
|
|||
destroyWindow = true;
|
||||
}
|
||||
|
||||
if(!destroyWindow &&
|
||||
r_gpuIndex->latchedString != NULL &&
|
||||
Q_stricmp(r_gpuIndex->latchedString, r_gpuIndex->string) != 0)
|
||||
{
|
||||
destroyWindow = true;
|
||||
}
|
||||
|
||||
if(rhi.frameBegun)
|
||||
{
|
||||
backEnd.renderFrame = qfalse;
|
||||
|
@ -5257,6 +5344,17 @@ namespace RHI
|
|||
barrier.UAV.pResource = NULL;
|
||||
rhi.commandList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
|
||||
void PrintGPUList()
|
||||
{
|
||||
CreateAdapterList();
|
||||
|
||||
ri.Printf(PRINT_ALL, "%s0^7. Default\n", S_COLOR_VAL);
|
||||
for(uint32_t i = 0; i < rhi.gpuCount; ++i)
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "%s%d^7. %s\n", S_COLOR_VAL, (int)i + 1, rhi.gpus[i].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R_WaitBeforeInputSampling()
|
||||
|
|
|
@ -1102,4 +1102,35 @@ namespace RHI
|
|||
uint32_t size = 0;
|
||||
uint32_t offset = 0;
|
||||
};
|
||||
|
||||
struct StringList
|
||||
{
|
||||
void Init(char* buffer_, size_t byteCount)
|
||||
{
|
||||
buffer = buffer_;
|
||||
written = 0;
|
||||
remaining = byteCount;
|
||||
}
|
||||
|
||||
void Append(const char* string)
|
||||
{
|
||||
const size_t l = strlen(string);
|
||||
if(remaining >= l + 2)
|
||||
{
|
||||
memcpy(buffer + written, string, l + 1);
|
||||
written += l + 1;
|
||||
remaining -= l + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Terminate()
|
||||
{
|
||||
buffer[written++] = '\0';
|
||||
remaining--;
|
||||
}
|
||||
|
||||
char* buffer = NULL;
|
||||
size_t written = 0;
|
||||
size_t remaining = 0;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -51,4 +51,6 @@ namespace RHI
|
|||
uint32_t srcRowByteCount;
|
||||
uint32_t dstRowByteCount;
|
||||
};
|
||||
|
||||
void PrintGPUList();
|
||||
}
|
||||
|
|
|
@ -128,6 +128,15 @@ S_COLOR_VAL " 0 " S_COLOR_HELP "= High performance\n" \
|
|||
S_COLOR_VAL " 1 " S_COLOR_HELP "= Low power\n" \
|
||||
S_COLOR_VAL " 2 " S_COLOR_HELP "= None"
|
||||
|
||||
#define help_r_gpuIndex \
|
||||
"sets the index of the GPU to use\n" \
|
||||
S_COLOR_VAL " 0 " S_COLOR_HELP "= Default\n" \
|
||||
"Use " S_COLOR_CMD "gpulist " S_COLOR_HELP "to see the numbered list of GPUs."
|
||||
|
||||
#define help_gpulist \
|
||||
"prints usable GPUs\n" \
|
||||
"The numbers can be used to set " S_COLOR_CVAR "r_gpuIndex" S_COLOR_HELP "."
|
||||
|
||||
#define help_r_colorMipLevels \
|
||||
"colorizes textures based on their mip level"
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ cvar_t *r_dither;
|
|||
cvar_t *r_rtColorFormat;
|
||||
cvar_t *r_depthClamp;
|
||||
cvar_t *r_gpuPreference;
|
||||
cvar_t *r_gpuIndex;
|
||||
|
||||
cvar_t *r_mipGenFilter;
|
||||
cvar_t *r_mipGenGamma;
|
||||
|
@ -316,6 +317,7 @@ static const cmdTableItem_t r_cmds[] =
|
|||
{ "shadermixeduse", R_ShaderMixedUse_f, NULL, "prints all mixed use issues" },
|
||||
{ "skinlist", R_SkinList_f, NULL, "prints loaded skins" },
|
||||
{ "modellist", R_Modellist_f, NULL, "prints loaded models" },
|
||||
{ "gpulist", RHI::PrintGPUList, NULL, help_gpulist },
|
||||
{ "screenshot", R_ScreenShotTGA_f, NULL, "takes a TARGA (.tga) screenshot" },
|
||||
{ "screenshotJPEG", R_ScreenShotJPG_f, NULL, "takes a JPEG (.jpg) screenshot" },
|
||||
{ "screenshotnc", R_ScreenShotNoConTGA_f, NULL, "takes a TARGA screenshot w/o the console" },
|
||||
|
@ -439,11 +441,15 @@ static const cvarTableItem_t r_cvars[] =
|
|||
},
|
||||
{
|
||||
&r_gpuPreference, "r_gpuPreference", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", XSTRING(GPUPREF_MAX), help_r_gpuPreference,
|
||||
"GPU selection", CVARCAT_DISPLAY | CVARCAT_PERFORMANCE, "Choose between low-power and high-performance devices", "",
|
||||
"GPU preference", CVARCAT_DISPLAY | CVARCAT_PERFORMANCE, "Choose between low-power and high-performance devices", "",
|
||||
CVAR_GUI_VALUE("0", "High performance", "")
|
||||
CVAR_GUI_VALUE("1", "Low power", "")
|
||||
CVAR_GUI_VALUE("2", "None", "")
|
||||
},
|
||||
{
|
||||
// GUI settings and data range are set by the RHI during init
|
||||
&r_gpuIndex, "r_gpuIndex", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", NULL, help_r_gpuIndex
|
||||
},
|
||||
{
|
||||
&r_vsync, "r_vsync", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, "enables v-sync",
|
||||
"V-Sync", CVARCAT_DISPLAY | CVARCAT_PERFORMANCE, "Enabling locks the framerate to the monitor's refresh rate", "",
|
||||
|
|
|
@ -1060,6 +1060,7 @@ extern cvar_t *r_dither; // enables dithering
|
|||
extern cvar_t *r_rtColorFormat; // color render target format, see RTCF_*
|
||||
extern cvar_t *r_depthClamp; // disables clipping vertices against the near and far clip planes
|
||||
extern cvar_t *r_gpuPreference; // shall we use high-performance or low-power devices?
|
||||
extern cvar_t *r_gpuIndex; // the index of the specific device to use
|
||||
|
||||
extern cvar_t *r_mipGenFilter; // if the string is invalid, Lanczos 4 is used
|
||||
extern cvar_t *r_mipGenGamma; // what gamma-space do we consider the textures to be in
|
||||
|
|
Loading…
Reference in a new issue