dist: Add prefer_discrete_gpu option to force use of dedicated GPU

Currently only implemented on Windows.

Fixes #680
This commit is contained in:
rdb 2022-12-06 14:45:49 +01:00
parent ecbd262ac4
commit ffbfdb22e0
3 changed files with 46 additions and 3 deletions

View File

@ -250,6 +250,7 @@ class build_apps(setuptools.Command):
self.log_filename = None
self.log_filename_strftime = False
self.log_append = False
self.prefer_discrete_gpu = False
self.requirements_path = os.path.join(os.getcwd(), 'requirements.txt')
self.use_optimized_wheels = True
self.optimized_wheel_index = ''
@ -516,11 +517,16 @@ class build_apps(setuptools.Command):
self.icon_objects.get('*', None),
)
if icon is not None:
if icon is not None or self.prefer_discrete_gpu:
pef = pefile.PEFile()
pef.open(runtime, 'r+')
pef.add_icon(icon)
pef.add_resource_section()
if icon is not None:
pef.add_icon(icon)
pef.add_resource_section()
if self.prefer_discrete_gpu:
if not pef.rename_export("SymbolPlaceholder___________________", "AmdPowerXpressRequestHighPerformance") or \
not pef.rename_export("SymbolPlaceholder__", "NvOptimusEnablement"):
self.warn("Failed to apply prefer_discrete_gpu, newer target Panda3D version may be required")
pef.write_changes()
pef.close()

View File

@ -605,6 +605,36 @@ class PEFile(object):
if self.res_rva.addr and self.res_rva.size:
self.resources.unpack_from(self.vmem, self.res_rva.addr)
def _mark_address_modified(self, rva):
for section in self.sections:
if rva >= section.vaddr and rva - section.vaddr <= section.size:
section.modified = True
def rename_export(self, old_name, new_name):
""" Renames a symbol in the export table. """
assert len(new_name) <= len(old_name)
new_name = new_name.ljust(len(old_name) + 1, '\0').encode('ascii')
start = self.exp_rva.addr
expdir = expdirtab(*unpack('<IIHHIIIIIII', self.vmem[start:start+40]))
if expdir.nnames == 0 or expdir.ordinals == 0 or expdir.names == 0:
return False
nptr = expdir.names
for i in range(expdir.nnames):
name_rva, = unpack('<I', self.vmem[nptr:nptr+4])
if name_rva != 0:
name = _unpack_zstring(self.vmem, name_rva)
if name == old_name:
self.vmem[name_rva:name_rva+len(new_name)] = new_name
self._mark_address_modified(name_rva)
return True
nptr += 4
return False
def get_export_address(self, symbol_name):
""" Finds the virtual address for a named export symbol. """

View File

@ -62,6 +62,13 @@ volatile struct {
// end up putting it in the .bss section for zero-initialized data.
} blobinfo = {(uint64_t)-1};
#ifdef _WIN32
// These placeholders can have their names changed by deploy-stub.
__declspec(dllexport) DWORD SymbolPlaceholder___________________ = 0x00000001;
__declspec(dllexport) DWORD SymbolPlaceholder__ = 0x00000001;
#endif
#ifdef MS_WINDOWS
# define WIN32_LEAN_AND_MEAN
# include <windows.h>