Add vk::Platform::describePlatform()
authorPyry Haulos <phaulos@google.com>
Fri, 22 Jan 2016 22:22:49 +0000 (14:22 -0800)
committerPyry Haulos <phaulos@google.com>
Fri, 22 Jan 2016 22:36:36 +0000 (14:36 -0800)
describePlatform() should log platform-specific architecture and version
information.

Implementation provided for Android, Win32, and X11/unix.

Change-Id: I0babdf2765f22d820f19c2f4c964b885e3395afc

external/vulkancts/framework/vulkan/vkPlatform.cpp
external/vulkancts/framework/vulkan/vkPlatform.hpp
framework/platform/X11/tcuX11Platform.cpp
framework/platform/android/tcuAndroidPlatform.cpp
framework/platform/android/tcuAndroidPlatform.hpp
framework/platform/android/tcuAndroidTestActivity.cpp
framework/platform/android/tcuAndroidUtil.cpp
framework/platform/android/tcuAndroidUtil.hpp
framework/platform/win32/tcuWin32Platform.cpp
framework/platform/win32/tcuWin32Platform.hpp

index 12332f0..6e958a7 100644 (file)
@@ -75,4 +75,9 @@ DeviceDriver::~DeviceDriver (void)
 #include "vkInstanceDriverImpl.inl"
 #include "vkDeviceDriverImpl.inl"
 
+void Platform::describePlatform (std::ostream& dst) const
+{
+       dst << "vk::Platform::describePlatform() not implemented";
+}
+
 } // vk
index 06b1603..fcbfaf5 100644 (file)
@@ -36,6 +36,8 @@
 
 #include "vkDefs.hpp"
 
+#include <ostream>
+
 namespace tcu
 {
 class FunctionLibrary;
@@ -110,11 +112,13 @@ protected:
 class Platform
 {
 public:
-                                               Platform                (void) {}
-                                               ~Platform               (void) {}
+                                               Platform                        (void) {}
+                                               ~Platform                       (void) {}
 
        // \todo [2015-01-05 pyry] Parametrize this to select for example debug library / interface?
-       virtual Library*        createLibrary   (void) const = 0;
+       virtual Library*        createLibrary           (void) const = 0;
+
+       virtual void            describePlatform        (std::ostream& dst) const;
 };
 
 } // vk
index 483a642..81c6712 100644 (file)
@@ -28,6 +28,7 @@
 #include "vkPlatform.hpp"
 #include "tcuX11.hpp"
 #include "tcuFunctionLibrary.hpp"
+#include "deMemory.h"
 
 #if defined (DEQP_SUPPORT_GLX)
 #      include "tcuX11GlxPlatform.hpp"
@@ -36,6 +37,7 @@
 #      include "tcuX11EglPlatform.hpp"
 #endif
 
+#include <sys/utsname.h>
 
 namespace tcu
 {
@@ -77,6 +79,19 @@ public:
        {
                return new VulkanLibrary();
        }
+
+       void describePlatform (std::ostream& dst) const
+       {
+               utsname         sysInfo;
+
+               deMemset(&sysInfo, 0, sizeof(sysInfo));
+
+               if (uname(&sysInfo) != 0)
+                       throw std::runtime_error("uname() failed");
+
+               dst << "OS: " << sysInfo.sysname << " " << sysInfo.release << " " << sysInfo.version << "\n";
+               dst << "CPU: " << sysInfo.machine << "\n";
+       }
 };
 
 class X11Platform : public tcu::Platform
index d9a46d5..89c5c5c 100644 (file)
@@ -22,6 +22,7 @@
  *//*--------------------------------------------------------------------*/
 
 #include "tcuAndroidPlatform.hpp"
+#include "tcuAndroidUtil.hpp"
 #include "gluRenderContext.hpp"
 #include "egluNativeDisplay.hpp"
 #include "egluNativeWindow.hpp"
@@ -159,7 +160,6 @@ eglu::NativeWindow* NativeWindowFactory::createWindow (eglu::NativeDisplay* nati
        return createWindow(params, format);
 }
 
-
 eglu::NativeWindow* NativeWindowFactory::createWindow (const eglu::WindowParams& params, int32_t format) const
 {
        Window* window = m_windowRegistry.tryAcquireWindow();
@@ -207,7 +207,8 @@ private:
 
 // Platform
 
-Platform::Platform (void)
+Platform::Platform (NativeActivity& activity)
+       : m_activity(activity)
 {
        m_nativeDisplayFactoryRegistry.registerFactory(new NativeDisplayFactory(m_windowRegistry));
        m_contextFactoryRegistry.registerFactory(new eglu::GLContextFactory(m_nativeDisplayFactoryRegistry));
@@ -228,5 +229,10 @@ vk::Library* Platform::createLibrary (void) const
        return new VulkanLibrary();
 }
 
+void Platform::describePlatform (std::ostream& dst) const
+{
+       tcu::Android::describePlatform(m_activity.getNativeActivity(), dst);
+}
+
 } // Android
 } // tcu
index 45406a6..63ea6a6 100644 (file)
@@ -29,6 +29,7 @@
 #include "gluPlatform.hpp"
 #include "vkPlatform.hpp"
 #include "tcuAndroidWindow.hpp"
+#include "tcuAndroidNativeActivity.hpp"
 
 namespace tcu
 {
@@ -38,7 +39,7 @@ namespace Android
 class Platform : public tcu::Platform, private eglu::Platform, private glu::Platform, private vk::Platform
 {
 public:
-                                                                       Platform                        (void);
+                                                                       Platform                        (NativeActivity& activity);
        virtual                                                 ~Platform                       (void);
 
        virtual bool                                    processEvents           (void);
@@ -50,8 +51,10 @@ public:
        WindowRegistry&                                 getWindowRegistry       (void) { return m_windowRegistry; }
 
        vk::Library*                                    createLibrary           (void) const;
+       void                                                    describePlatform        (std::ostream& dst) const;
 
 private:
+       NativeActivity&                                 m_activity;
        WindowRegistry                                  m_windowRegistry;
 };
 
index 31b7ac1..b8cff3c 100644 (file)
@@ -41,6 +41,7 @@ namespace Android
 TestThread::TestThread (NativeActivity& activity, const CommandLine& cmdLine)
        : RenderThread  (activity)
        , m_cmdLine             (cmdLine)
+       , m_platform    (activity)
        , m_archive             (activity.getNativeActivity()->assetManager)
        , m_log                 (m_cmdLine.getLogFileName(), m_cmdLine.getLogFlags())
        , m_app                 (m_platform, m_archive, m_log, m_cmdLine)
index 7f29c6a..3c09ce9 100644 (file)
 
 #include "tcuAndroidUtil.hpp"
 
+#include <vector>
+
 namespace tcu
 {
 namespace Android
 {
 
 using std::string;
+using std::vector;
+
+void checkJNIException (JNIEnv* env)
+{
+       if (env->ExceptionCheck())
+       {
+               env->ExceptionDescribe();
+               env->ExceptionClear();
+               throw std::runtime_error("Got JNI exception");
+       }
+}
+
+string getJNIStringValue (JNIEnv* env, jstring jniStr)
+{
+       const char*             ptr             = env->GetStringUTFChars(jniStr, DE_NULL);
+       const string    str             = string(ptr);
+
+       env->ReleaseStringUTFChars(jniStr, ptr);
+
+       return str;
+}
 
 static string getIntentStringExtra (JNIEnv* env, jobject activity, const char* name)
 {
@@ -49,12 +72,7 @@ static string getIntentStringExtra (JNIEnv* env, jobject activity, const char* n
        env->DeleteLocalRef(extraName);
 
        if (extraStr)
-       {
-               const char* ptr = env->GetStringUTFChars(extraStr, DE_NULL);
-               string str = string(ptr);
-               env->ReleaseStringUTFChars(extraStr, ptr);
-               return str;
-       }
+               return getJNIStringValue(env, extraStr);
        else
                return string();
 }
@@ -92,5 +110,175 @@ ScreenOrientation mapScreenRotation (ScreenRotation rotation)
        }
 }
 
+template<typename Type>
+const char* getJNITypeStr (void);
+
+template<>
+const char* getJNITypeStr<int> (void)
+{
+       return "I";
+}
+
+template<>
+const char* getJNITypeStr<string> (void)
+{
+       return "Ljava/lang/String;";
+}
+
+template<>
+const char* getJNITypeStr<vector<string> > (void)
+{
+       return "[Ljava/lang/String;";
+}
+
+template<typename FieldType>
+FieldType getStaticFieldValue (JNIEnv* env, jclass cls, jfieldID fieldId);
+
+template<>
+int getStaticFieldValue<int> (JNIEnv* env, jclass cls, jfieldID fieldId)
+{
+       DE_ASSERT(cls && fieldId);
+       return env->GetStaticIntField(cls, fieldId);
+}
+
+template<>
+string getStaticFieldValue<string> (JNIEnv* env, jclass cls, jfieldID fieldId)
+{
+       const jstring   jniStr  = (jstring)env->GetStaticObjectField(cls, fieldId);
+
+       if (jniStr)
+               return getJNIStringValue(env, jniStr);
+       else
+               return string();
+}
+
+template<>
+vector<string> getStaticFieldValue<vector<string> > (JNIEnv* env, jclass cls, jfieldID fieldId)
+{
+       const jobjectArray      array           = (jobjectArray)env->GetStaticObjectField(cls, fieldId);
+       vector<string>          result;
+
+       checkJNIException(env);
+
+       if (array)
+       {
+               const int       numElements             = env->GetArrayLength(array);
+
+               for (int ndx = 0; ndx < numElements; ndx++)
+               {
+                       const jstring   jniStr  = (jstring)env->GetObjectArrayElement(array, ndx);
+
+                       checkJNIException(env);
+
+                       if (jniStr)
+                               result.push_back(getJNIStringValue(env, jniStr));
+               }
+       }
+
+       return result;
+}
+
+template<typename FieldType>
+FieldType getStaticField (JNIEnv* env, const char* className, const char* fieldName)
+{
+       const jclass    cls                     = env->FindClass(className);
+       const jfieldID  fieldId         = cls ? env->GetStaticFieldID(cls, fieldName, getJNITypeStr<FieldType>()) : (jfieldID)0;
+
+       checkJNIException(env);
+
+       if (cls && fieldId)
+               return getStaticFieldValue<FieldType>(env, cls, fieldId);
+       else
+               return FieldType();
+}
+
+class ScopedJNIEnv
+{
+public:
+
+                                       ScopedJNIEnv    (JavaVM* vm);
+                                       ~ScopedJNIEnv   (void);
+
+       JavaVM*                 getVM                   (void) const { return m_vm;             }
+       JNIEnv*                 getEnv                  (void) const { return m_env;    }
+
+private:
+       JavaVM* const   m_vm;
+       JNIEnv*                 m_env;
+       bool                    m_detach;
+};
+
+ScopedJNIEnv::ScopedJNIEnv (JavaVM* vm)
+       : m_vm          (vm)
+       , m_env         (DE_NULL)
+       , m_detach      (false)
+{
+       const int       getEnvRes       = m_vm->GetEnv((void**)&m_env, JNI_VERSION_1_6);
+
+       if (getEnvRes == JNI_EDETACHED)
+       {
+               if (m_vm->AttachCurrentThread(&m_env, DE_NULL) != JNI_OK)
+                       throw std::runtime_error("JNI AttachCurrentThread() failed");
+
+               m_detach = true;
+       }
+       else if (getEnvRes != JNI_OK)
+               throw std::runtime_error("JNI GetEnv() failed");
+
+       DE_ASSERT(m_env);
+}
+
+ScopedJNIEnv::~ScopedJNIEnv (void)
+{
+       if (m_detach)
+               m_vm->DetachCurrentThread();
+}
+
+void describePlatform (ANativeActivity* activity, std::ostream& dst)
+{
+       const ScopedJNIEnv      env                             (activity->vm);
+       const char* const       buildClass              = "android/os/Build";
+       const char* const       versionClass    = "android/os/Build$VERSION";
+
+       static const struct
+       {
+               const char*             classPath;
+               const char*             className;
+               const char*             fieldName;
+       } s_stringFields[] =
+       {
+               { buildClass,   "Build",                        "BOARD"                 },
+               { buildClass,   "Build",                        "BRAND"                 },
+               { buildClass,   "Build",                        "DEVICE"                },
+               { buildClass,   "Build",                        "DISPLAY"               },
+               { buildClass,   "Build",                        "FINGERPRINT"   },
+               { buildClass,   "Build",                        "HARDWARE"              },
+               { buildClass,   "Build",                        "MANUFACTURER"  },
+               { buildClass,   "Build",                        "MODEL"                 },
+               { buildClass,   "Build",                        "PRODUCT"               },
+               { buildClass,   "Build",                        "TAGS"                  },
+               { buildClass,   "Build",                        "TYPE"                  },
+               { versionClass, "Build.VERSION",        "RELEASE"               },
+       };
+
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_stringFields); ndx++)
+               dst << s_stringFields[ndx].className << "." << s_stringFields[ndx].fieldName
+                       << ": " << getStaticField<string>(env.getEnv(), s_stringFields[ndx].classPath, s_stringFields[ndx].fieldName)
+                       << "\n";
+
+       dst << "Build.VERSION.SDK_INT: " << getStaticField<int>(env.getEnv(), versionClass, "SDK_INT") << "\n";
+
+       {
+               const vector<string>    supportedAbis   = getStaticField<vector<string> >(env.getEnv(), buildClass, "SUPPORTED_ABIS");
+
+               dst << "Build.SUPPORTED_ABIS: ";
+
+               for (size_t ndx = 0; ndx < supportedAbis.size(); ndx++)
+                       dst << (ndx != 0 ? ", " : "") << supportedAbis[ndx];
+
+               dst << "\n";
+       }
+}
+
 } // Android
 } // tcu
index a625433..254e890 100644 (file)
@@ -27,6 +27,7 @@
 #include "tcuCommandLine.hpp"
 
 #include <string>
+#include <ostream>
 
 #include <android/native_activity.h>
 
@@ -49,6 +50,8 @@ void                          setRequestedOrientation         (ANativeActivity* activity, ScreenOrientation o
 
 ScreenOrientation      mapScreenRotation                       (ScreenRotation rotation);
 
+void                           describePlatform                        (ANativeActivity* activity, std::ostream& dst);
+
 } // Android
 } // tcu
 
index d5a1625..2cb00aa 100644 (file)
  * \brief Win32 platform port.
  *//*--------------------------------------------------------------------*/
 
+// \todo [2016-01-22 pyry] GetVersionEx() used by getOSInfo() is deprecated.
+//                                                Find a way to get version info without using deprecated APIs.
+#pragma warning(disable : 4996)
+
 #include "tcuWin32Platform.hpp"
 #include "tcuWGLContextFactory.hpp"
 #include "tcuFunctionLibrary.hpp"
+#include "tcuFormatUtil.hpp"
+
+#include "deMemory.h"
 
 #if defined(DEQP_SUPPORT_EGL)
 #      include "tcuWin32EGLNativeDisplayFactory.hpp"
@@ -37,7 +44,7 @@ class VulkanLibrary : public vk::Library
 {
 public:
        VulkanLibrary (void)
-               : m_library     ("vulkan-1.dll")
+               : m_library     ("nv-vk64.dll")
                , m_driver      (m_library)
        {
        }
@@ -111,6 +118,84 @@ vk::Library* Win32Platform::createLibrary (void) const
        return new VulkanLibrary();
 }
 
+const char* getProductTypeName (WORD productType)
+{
+       switch (productType)
+       {
+               case VER_NT_DOMAIN_CONTROLLER:  return "Windows Server (domain controller)";
+               case VER_NT_SERVER:                             return "Windows Server";
+               case VER_NT_WORKSTATION:                return "Windows NT";
+               default:                                                return DE_NULL;
+       }
+}
+
+static void getOSInfo (std::ostream& dst)
+{
+       OSVERSIONINFOEX osInfo;
+
+       deMemset(&osInfo, 0, sizeof(osInfo));
+       osInfo.dwOSVersionInfoSize = (DWORD)sizeof(osInfo);
+
+       GetVersionEx((OSVERSIONINFO*)&osInfo);
+
+       {
+               const char* const       productName     = getProductTypeName(osInfo.wProductType);
+
+               if (productName)
+                       dst << productName;
+               else
+                       dst << "unknown product " << tcu::toHex(osInfo.wProductType);
+       }
+
+       dst << " " << osInfo.dwMajorVersion << "." << osInfo.dwMinorVersion
+               << ", service pack " << osInfo.wServicePackMajor << "." << osInfo.wServicePackMinor
+               << ", build " << osInfo.dwBuildNumber;
+}
+
+const char* getProcessorArchitectureName (WORD arch)
+{
+       switch (arch)
+       {
+               case PROCESSOR_ARCHITECTURE_AMD64:              return "AMD64";
+               case PROCESSOR_ARCHITECTURE_ARM:                return "ARM";
+               case PROCESSOR_ARCHITECTURE_IA64:               return "IA64";
+               case PROCESSOR_ARCHITECTURE_INTEL:              return "INTEL";
+               case PROCESSOR_ARCHITECTURE_UNKNOWN:    return "UNKNOWN";
+               default:                                                                return DE_NULL;
+       }
+}
+
+static void getProcessorInfo (std::ostream& dst)
+{
+       SYSTEM_INFO     sysInfo;
+
+       deMemset(&sysInfo, 0, sizeof(sysInfo));
+       GetSystemInfo(&sysInfo);
+
+       dst << "arch ";
+       {
+               const char* const       archName        = getProcessorArchitectureName(sysInfo.wProcessorArchitecture);
+
+               if (archName)
+                       dst << archName;
+               else
+                       dst << tcu::toHex(sysInfo.wProcessorArchitecture);
+       }
+
+       dst << ", level " << tcu::toHex(sysInfo.wProcessorLevel) << ", revision " << tcu::toHex(sysInfo.wProcessorRevision);
+}
+
+void Win32Platform::describePlatform (std::ostream& dst) const
+{
+       dst << "OS: ";
+       getOSInfo(dst);
+       dst << "\n";
+
+       dst << "CPU: ";
+       getProcessorInfo(dst);
+       dst << "\n";
+}
+
 } // tcu
 
 // Create platform
index 8fc172b..ba62105 100644 (file)
@@ -59,6 +59,7 @@ public:
 
 private:
        vk::Library*                    createLibrary           (void) const;
+       void                                    describePlatform        (std::ostream& dst) const;
 
        HINSTANCE                               m_instance;
 };