Skip to content

Commit

Permalink
#558: detect the version number using NVAPI on win32
Browse files Browse the repository at this point in the history
git-svn-id: https://xpra.org/svn/Xpra/trunk@10240 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Aug 8, 2015
1 parent 4fc8460 commit 8963324
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 14 deletions.
19 changes: 19 additions & 0 deletions src/setup.py
Expand Up @@ -154,6 +154,7 @@ def is_msvc():
WIN32_BUILD_LIB_PREFIX = os.environ.get("XPRA_WIN32_BUILD_LIB_PREFIX", "C:\\")
nvenc4_sdk = WIN32_BUILD_LIB_PREFIX + "nvenc_4.0.0_sdk"
nvenc5_sdk = WIN32_BUILD_LIB_PREFIX + "nvenc_5.0.1_sdk"
nvapi_path = WIN32_BUILD_LIB_PREFIX + "NVAPI"
try:
import pycuda
except:
Expand Down Expand Up @@ -880,6 +881,7 @@ def pkgconfig(*pkgs_options, **ekw):
"xpra/codecs/csc_cython/colorspace_converter.c",
"xpra/codecs/xor/cyxor.c",
"xpra/codecs/argb/argb.c",
"xpra/codecs/nvapi_version.c",
"xpra/server/stats/cystats.c",
"xpra/server/region.c",
"etc/xpra/xpra.conf",
Expand Down Expand Up @@ -1500,6 +1502,17 @@ def add_keywords(path_dirs=[], inc_dirs=[], lib_dirs=[], libs=[], noref=True, no
#assume 32-bit for now:
#add_data_files('', ["C:\\Windows\System32\nvcuda.dll"])
#add_data_files('', ["%s/nvencodeapi.dll" % nvenc_bin_dir])
elif "nvapi" in pkgs_options[0]:
nvapi_include_dir = nvapi_path
import struct
if struct.calcsize("P")==4:
nvapi_lib_names = ["nvapi"]
nvapi_lib_dir = os.path.join(nvapi_path, "x86")
else:
nvapi_lib_names = ["nvapi64"]
nvapi_lib_dir = os.path.join(nvapi_path, "amd64")

add_keywords([], [nvapi_include_dir], [nvapi_lib_dir], nvapi_lib_names)
elif "pygobject-2.0" in pkgs_options[0]:
dirs = (python_include_path,
pygtk_include_dir, atk_include_dir, gtk2_include_dir,
Expand Down Expand Up @@ -1877,6 +1890,12 @@ def cython_add(*args, **kwargs):
toggle_packages(nvenc4_ENABLED, "xpra.codecs.nvenc4")
toggle_packages(nvenc5_ENABLED, "xpra.codecs.nvenc5")
toggle_packages(nvenc4_ENABLED or nvenc5_ENABLED, "xpra.codecs.cuda_common", "xpra.codecs.nv_util")
if (nvenc4_ENABLED or nvenc5_ENABLED) and WIN32:
cython_add(Extension("xpra.codecs.nvapi_version",
["xpra/codecs/nvapi_version.pyx"],
**pkgconfig("nvapi")
))

if nvenc4_ENABLED or nvenc5_ENABLED:
#find nvcc:
nvcc = None
Expand Down
48 changes: 34 additions & 14 deletions src/xpra/codecs/nv_util.py
Expand Up @@ -7,25 +7,45 @@
import os
from xpra.log import Logger
log = Logger("encoder", "nvenc")
from xpra.util import pver


def identify_nvidia_module_version():
if os.name!="posix":
return None
from xpra.os_util import load_binary_file
v = load_binary_file("/proc/driver/nvidia/version")
if not v:
log.warn("Nvidia kernel module not installed?")
return []
KSTR = "Kernel Module"
p = v.find(KSTR)
if not p:
log.warn("unknown Nvidia kernel module version")
return []
v = v[p+len(KSTR):].strip().split(" ")[0]
if not sys.platform.startswith("win"):
log.warn("Warning: unable to identify the NVidia driver version on this platform")
return None
#try the nvapi call:
try:
from xpra.codecs.nvapi_version import get_driver_version #@UnresolvedImport
v = get_driver_version()
log("NVAPI get_driver_version()=%s", v)
except Exception as e:
log.warn("failed to get the driver version through NVAPI:")
log.warn(" %s", e)
else:
from xpra.os_util import load_binary_file
v = load_binary_file("/proc/driver/nvidia/version")
if not v:
log.warn("Nvidia kernel module not installed?")
return []
KSTR = "Kernel Module"
p = v.find(KSTR)
if not p:
log.warn("unknown Nvidia kernel module version")
return []
v = v[p+len(KSTR):].strip().split(" ")[0]
v = v.split(".")
#only keep numeric values:
numver = []
try:
numver = [int(x) for x in v.split(".")]
log.info("Nvidia kernel module version %s", v)
for x in v:
try:
numver.append(int(x))
except ValueError:
if len(numver)==0:
raise
log.info("Nvidia driver version %s", pver(numver))
return numver
except Exception as e:
log.warn("failed to parse Nvidia kernel module version '%s': %s", v, e)
Expand Down
66 changes: 66 additions & 0 deletions src/xpra/codecs/nvapi_version.pyx
@@ -0,0 +1,66 @@
# This file is part of Xpra.
# Copyright (C) 2015 Antoine Martin <antoine@devloop.org.uk>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

import sys
import os
from xpra.log import Logger
log = Logger("encoder", "nvenc")

from libc.stdint cimport uint32_t


cdef extern from "nvapi.h":
#define NVAPI_SHORT_STRING_MAX 64
int NVAPI_SHORT_STRING_MAX
ctypedef uint32_t NvU32
ctypedef char[64] NvAPI_ShortString
ctypedef uint32_t NVAPI_INTERFACE
ctypedef uint32_t NvAPI_Status

ctypedef struct NV_DISPLAY_DRIVER_VERSION:
NvU32 version # Structure version
NvU32 drvVersion
NvU32 bldChangeListNum
NvAPI_ShortString szBuildBranchString
NvAPI_ShortString szAdapterString

NvAPI_Status NvAPI_Initialize()
NvAPI_Status NvAPI_Unload()
NvAPI_Status NvAPI_GetErrorMessage(NvAPI_Status nr,NvAPI_ShortString szDesc)
NvAPI_Status NvAPI_SYS_GetDriverAndBranchVersion(NvU32* pDriverVersion, NvAPI_ShortString szBuildBranchString)

def raiseNVAPI(r, msg):
if r!=0:
raise Exception("error %s %s" % (r, msg))

def get_driver_version():
cdef NvAPI_Status r
r = NvAPI_Initialize()
raiseNVAPI(r, "NvAPI_Initialize")
cdef NvU32 driverVersion
cdef NvAPI_ShortString buildBranch
try:
r = NvAPI_SYS_GetDriverAndBranchVersion(&driverVersion, buildBranch)
raiseNVAPI(r, "NvAPI_SYS_GetDriverAndBranchVersion")
log("DriverVersion: %s", driverVersion)
log("Build Branch: %s", buildBranch)
return [driverVersion//100, driverVersion%100, str(buildBranch)]
finally:
r = NvAPI_Unload()
raiseNVAPI(r, "NvAPI_Unload")

def main():
if "-v" in sys.argv or "--verbose" in sys.argv:
log.enable_debug()

from xpra.platform import init, clean
try:
init("Nvidia-Info", "Nvidia Info")
log.info("%s", get_driver_version())
finally:
clean()

if __name__ == "__main__":
main()

0 comments on commit 8963324

Please sign in to comment.