mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-29 07:12:18 +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)
|
1 - low power (integrated graphics)
|
||||||
2 - none
|
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
|
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
|
it's a trade-off between frame time consistency and CPU usage
|
||||||
set to 2000 if you have a struggling old/low-power CPU
|
set to 2000 if you have a struggling old/low-power CPU
|
||||||
|
|
|
@ -634,6 +634,12 @@ namespace RHI
|
||||||
ResourceStates::Flags newState = ResourceStates::Common;
|
ResourceStates::Flags newState = ResourceStates::Common;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GPU
|
||||||
|
{
|
||||||
|
char name[256];
|
||||||
|
LUID uniqueId;
|
||||||
|
};
|
||||||
|
|
||||||
struct RHIPrivate
|
struct RHIPrivate
|
||||||
{
|
{
|
||||||
bool initialized;
|
bool initialized;
|
||||||
|
@ -733,6 +739,8 @@ namespace RHI
|
||||||
PIX pix;
|
PIX pix;
|
||||||
int64_t beforeInputSamplingUS;
|
int64_t beforeInputSamplingUS;
|
||||||
int64_t beforeRenderingUS;
|
int64_t beforeRenderingUS;
|
||||||
|
GPU gpus[16];
|
||||||
|
uint32_t gpuCount;
|
||||||
|
|
||||||
// immediate-mode barrier API
|
// immediate-mode barrier API
|
||||||
TextureBarrier textureBarriers[64];
|
TextureBarrier textureBarriers[64];
|
||||||
|
@ -1453,6 +1461,52 @@ namespace RHI
|
||||||
return true;
|
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)
|
static IDXGIAdapter1* FindMostSuitableAdapter(IDXGIFactory1* factory, int enginePreference)
|
||||||
{
|
{
|
||||||
IDXGIAdapter1* adapter = NULL;
|
IDXGIAdapter1* adapter = NULL;
|
||||||
|
@ -3145,7 +3199,15 @@ namespace RHI
|
||||||
D3D(CreateDXGIFactory1(IID_PPV_ARGS(&rhi.factory)));
|
D3D(CreateDXGIFactory1(IID_PPV_ARGS(&rhi.factory)));
|
||||||
#endif
|
#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];
|
char adapterName[256];
|
||||||
const char* adapterNamePtr = "unknown";
|
const char* adapterNamePtr = "unknown";
|
||||||
|
@ -3158,6 +3220,24 @@ namespace RHI
|
||||||
ri.Printf(PRINT_ALL, "Selected graphics adapter: %s\n", adapterNamePtr);
|
ri.Printf(PRINT_ALL, "Selected graphics adapter: %s\n", adapterNamePtr);
|
||||||
Q_strncpyz(rhi.adapterName, adapterNamePtr, sizeof(rhi.adapterName));
|
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)));
|
D3D(D3D12CreateDevice(rhi.adapter, FeatureLevel, IID_PPV_ARGS(&rhi.device)));
|
||||||
|
|
||||||
|
@ -3475,6 +3555,13 @@ namespace RHI
|
||||||
destroyWindow = true;
|
destroyWindow = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!destroyWindow &&
|
||||||
|
r_gpuIndex->latchedString != NULL &&
|
||||||
|
Q_stricmp(r_gpuIndex->latchedString, r_gpuIndex->string) != 0)
|
||||||
|
{
|
||||||
|
destroyWindow = true;
|
||||||
|
}
|
||||||
|
|
||||||
if(rhi.frameBegun)
|
if(rhi.frameBegun)
|
||||||
{
|
{
|
||||||
backEnd.renderFrame = qfalse;
|
backEnd.renderFrame = qfalse;
|
||||||
|
@ -5257,6 +5344,17 @@ namespace RHI
|
||||||
barrier.UAV.pResource = NULL;
|
barrier.UAV.pResource = NULL;
|
||||||
rhi.commandList->ResourceBarrier(1, &barrier);
|
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()
|
void R_WaitBeforeInputSampling()
|
||||||
|
|
|
@ -1102,4 +1102,35 @@ namespace RHI
|
||||||
uint32_t size = 0;
|
uint32_t size = 0;
|
||||||
uint32_t offset = 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 srcRowByteCount;
|
||||||
uint32_t dstRowByteCount;
|
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 " 1 " S_COLOR_HELP "= Low power\n" \
|
||||||
S_COLOR_VAL " 2 " S_COLOR_HELP "= None"
|
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 \
|
#define help_r_colorMipLevels \
|
||||||
"colorizes textures based on their mip level"
|
"colorizes textures based on their mip level"
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ cvar_t *r_dither;
|
||||||
cvar_t *r_rtColorFormat;
|
cvar_t *r_rtColorFormat;
|
||||||
cvar_t *r_depthClamp;
|
cvar_t *r_depthClamp;
|
||||||
cvar_t *r_gpuPreference;
|
cvar_t *r_gpuPreference;
|
||||||
|
cvar_t *r_gpuIndex;
|
||||||
|
|
||||||
cvar_t *r_mipGenFilter;
|
cvar_t *r_mipGenFilter;
|
||||||
cvar_t *r_mipGenGamma;
|
cvar_t *r_mipGenGamma;
|
||||||
|
@ -316,6 +317,7 @@ static const cmdTableItem_t r_cmds[] =
|
||||||
{ "shadermixeduse", R_ShaderMixedUse_f, NULL, "prints all mixed use issues" },
|
{ "shadermixeduse", R_ShaderMixedUse_f, NULL, "prints all mixed use issues" },
|
||||||
{ "skinlist", R_SkinList_f, NULL, "prints loaded skins" },
|
{ "skinlist", R_SkinList_f, NULL, "prints loaded skins" },
|
||||||
{ "modellist", R_Modellist_f, NULL, "prints loaded models" },
|
{ "modellist", R_Modellist_f, NULL, "prints loaded models" },
|
||||||
|
{ "gpulist", RHI::PrintGPUList, NULL, help_gpulist },
|
||||||
{ "screenshot", R_ScreenShotTGA_f, NULL, "takes a TARGA (.tga) screenshot" },
|
{ "screenshot", R_ScreenShotTGA_f, NULL, "takes a TARGA (.tga) screenshot" },
|
||||||
{ "screenshotJPEG", R_ScreenShotJPG_f, NULL, "takes a JPEG (.jpg) screenshot" },
|
{ "screenshotJPEG", R_ScreenShotJPG_f, NULL, "takes a JPEG (.jpg) screenshot" },
|
||||||
{ "screenshotnc", R_ScreenShotNoConTGA_f, NULL, "takes a TARGA screenshot w/o the console" },
|
{ "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,
|
&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("0", "High performance", "")
|
||||||
CVAR_GUI_VALUE("1", "Low power", "")
|
CVAR_GUI_VALUE("1", "Low power", "")
|
||||||
CVAR_GUI_VALUE("2", "None", "")
|
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",
|
&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", "",
|
"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_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_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_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_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
|
extern cvar_t *r_mipGenGamma; // what gamma-space do we consider the textures to be in
|
||||||
|
|
Loading…
Reference in a new issue