From 48fa029dd11bb09d4aca8e0a420781e3ec07a3a2 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Fri, 14 May 2021 11:15:00 -0300 Subject: Python GPU: New 'platform' module This module exposes the platform utils defined in the GPU module in C. This will be useful for porting existing code with `bgl` to `gpu`. Reviewed By: fclem, brecht, campbellbarton Maniphest Tasks: T80730 Part of D11147 --- source/blender/gpu/GPU_platform.h | 3 + source/blender/gpu/intern/gpu_platform.cc | 73 +++++++++++++++++---- source/blender/gpu/intern/gpu_platform_private.hh | 16 +++-- source/blender/gpu/opengl/gl_backend.cc | 77 ++++++++++++----------- 4 files changed, 113 insertions(+), 56 deletions(-) (limited to 'source/blender/gpu') diff --git a/source/blender/gpu/GPU_platform.h b/source/blender/gpu/GPU_platform.h index c457b829bf7..fa7d5d7fba8 100644 --- a/source/blender/gpu/GPU_platform.h +++ b/source/blender/gpu/GPU_platform.h @@ -68,6 +68,9 @@ extern "C" { bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver); eGPUSupportLevel GPU_platform_support_level(void); +const char *GPU_platform_vendor(void); +const char *GPU_platform_renderer(void); +const char *GPU_platform_version(void); const char *GPU_platform_support_level_key(void); const char *GPU_platform_gpu_name(void); diff --git a/source/blender/gpu/intern/gpu_platform.cc b/source/blender/gpu/intern/gpu_platform.cc index 6b9878f2ba4..49dde473300 100644 --- a/source/blender/gpu/intern/gpu_platform.cc +++ b/source/blender/gpu/intern/gpu_platform.cc @@ -41,10 +41,10 @@ namespace blender::gpu { GPUPlatformGlobal GPG; -void GPUPlatformGlobal::create_key(eGPUSupportLevel support_level, - const char *vendor, - const char *renderer, - const char *version) +static char *create_key(eGPUSupportLevel support_level, + const char *vendor, + const char *renderer, + const char *version) { DynStr *ds = BLI_dynstr_new(); BLI_dynstr_appendf(ds, "{%s/%s/%s}=", vendor, renderer, version); @@ -58,29 +58,56 @@ void GPUPlatformGlobal::create_key(eGPUSupportLevel support_level, BLI_dynstr_append(ds, "UNSUPPORTED"); } - support_key = BLI_dynstr_get_cstring(ds); + char *support_key = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); BLI_str_replace_char(support_key, '\n', ' '); BLI_str_replace_char(support_key, '\r', ' '); + return support_key; } -void GPUPlatformGlobal::create_gpu_name(const char *vendor, - const char *renderer, - const char *version) +static char *create_gpu_name(const char *vendor, const char *renderer, const char *version) { DynStr *ds = BLI_dynstr_new(); BLI_dynstr_appendf(ds, "%s %s %s", vendor, renderer, version); - gpu_name = BLI_dynstr_get_cstring(ds); + char *gpu_name = BLI_dynstr_get_cstring(ds); BLI_dynstr_free(ds); BLI_str_replace_char(gpu_name, '\n', ' '); BLI_str_replace_char(gpu_name, '\r', ' '); + return gpu_name; +} + +void GPUPlatformGlobal::init(eGPUDeviceType gpu_device, + eGPUOSType os_type, + eGPUDriverType driver_type, + eGPUSupportLevel gpu_support_level, + const char *vendor_str, + const char *renderer_str, + const char *version_str) +{ + this->clear(); + + this->initialized = true; + + this->device = gpu_device; + this->os = os_type; + this->driver = driver_type; + this->support_level = gpu_support_level; + + this->vendor = BLI_strdup(vendor_str); + this->renderer = BLI_strdup(renderer_str); + this->version = BLI_strdup(version_str); + this->support_key = create_key(gpu_support_level, vendor_str, renderer_str, version_str); + this->gpu_name = create_gpu_name(vendor_str, renderer_str, version_str); } void GPUPlatformGlobal::clear() { - MEM_SAFE_FREE(GPG.support_key); - MEM_SAFE_FREE(GPG.gpu_name); + MEM_SAFE_FREE(vendor); + MEM_SAFE_FREE(renderer); + MEM_SAFE_FREE(version); + MEM_SAFE_FREE(support_key); + MEM_SAFE_FREE(gpu_name); initialized = false; } @@ -96,22 +123,44 @@ using namespace blender::gpu; eGPUSupportLevel GPU_platform_support_level() { + BLI_assert(GPG.initialized); return GPG.support_level; } -const char *GPU_platform_support_level_key() +const char *GPU_platform_vendor(void) +{ + BLI_assert(GPG.initialized); + return GPG.vendor; +} + +const char *GPU_platform_renderer(void) +{ + BLI_assert(GPG.initialized); + return GPG.renderer; +} + +const char *GPU_platform_version(void) +{ + BLI_assert(GPG.initialized); + return GPG.version; +} + +const char *GPU_platform_support_level_key(void) { + BLI_assert(GPG.initialized); return GPG.support_key; } const char *GPU_platform_gpu_name(void) { + BLI_assert(GPG.initialized); return GPG.gpu_name; } /* GPU Types */ bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver) { + BLI_assert(GPG.initialized); return (GPG.device & device) && (GPG.os & os) && (GPG.driver & driver); } diff --git a/source/blender/gpu/intern/gpu_platform_private.hh b/source/blender/gpu/intern/gpu_platform_private.hh index 02d99efa4a9..f823269ab54 100644 --- a/source/blender/gpu/intern/gpu_platform_private.hh +++ b/source/blender/gpu/intern/gpu_platform_private.hh @@ -34,16 +34,20 @@ class GPUPlatformGlobal { eGPUOSType os; eGPUDriverType driver; eGPUSupportLevel support_level; + char *vendor = nullptr; + char *renderer = nullptr; + char *version = nullptr; char *support_key = nullptr; char *gpu_name = nullptr; public: - void create_key(eGPUSupportLevel support_level, - const char *vendor, - const char *renderer, - const char *version); - - void create_gpu_name(const char *vendor, const char *renderer, const char *version); + void init(eGPUDeviceType gpu_device, + eGPUOSType os_type, + eGPUDriverType driver_type, + eGPUSupportLevel gpu_support_level, + const char *vendor_str, + const char *renderer_str, + const char *version_str); void clear(void); }; diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index 89bad1c9a4b..9d9cc62c633 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -41,39 +41,42 @@ namespace blender::gpu { void GLBackend::platform_init() { BLI_assert(!GPG.initialized); - GPG.initialized = true; + + const char *vendor = (const char *)glGetString(GL_VENDOR); + const char *renderer = (const char *)glGetString(GL_RENDERER); + const char *version = (const char *)glGetString(GL_VERSION); + eGPUDeviceType device = GPU_DEVICE_ANY; + eGPUOSType os = GPU_OS_ANY; + eGPUDriverType driver = GPU_DRIVER_ANY; + eGPUSupportLevel support_level = GPU_SUPPORT_LEVEL_SUPPORTED; #ifdef _WIN32 - GPG.os = GPU_OS_WIN; + os = GPU_OS_WIN; #elif defined(__APPLE__) - GPG.os = GPU_OS_MAC; + os = GPU_OS_MAC; #else - GPG.os = GPU_OS_UNIX; + os = GPU_OS_UNIX; #endif - const char *vendor = (const char *)glGetString(GL_VENDOR); - const char *renderer = (const char *)glGetString(GL_RENDERER); - const char *version = (const char *)glGetString(GL_VERSION); - if (strstr(vendor, "ATI") || strstr(vendor, "AMD")) { - GPG.device = GPU_DEVICE_ATI; - GPG.driver = GPU_DRIVER_OFFICIAL; + device = GPU_DEVICE_ATI; + driver = GPU_DRIVER_OFFICIAL; } else if (strstr(vendor, "NVIDIA")) { - GPG.device = GPU_DEVICE_NVIDIA; - GPG.driver = GPU_DRIVER_OFFICIAL; + device = GPU_DEVICE_NVIDIA; + driver = GPU_DRIVER_OFFICIAL; } else if (strstr(vendor, "Intel") || /* src/mesa/drivers/dri/intel/intel_context.c */ strstr(renderer, "Mesa DRI Intel") || strstr(renderer, "Mesa DRI Mobile Intel")) { - GPG.device = GPU_DEVICE_INTEL; - GPG.driver = GPU_DRIVER_OFFICIAL; + device = GPU_DEVICE_INTEL; + driver = GPU_DRIVER_OFFICIAL; if (strstr(renderer, "UHD Graphics") || /* Not UHD but affected by the same bugs. */ strstr(renderer, "HD Graphics 530") || strstr(renderer, "Kaby Lake GT2") || strstr(renderer, "Whiskey Lake")) { - GPG.device |= GPU_DEVICE_INTEL_UHD; + device |= GPU_DEVICE_INTEL_UHD; } } else if ((strstr(renderer, "Mesa DRI R")) || @@ -81,49 +84,47 @@ void GLBackend::platform_init() (strstr(renderer, "AMD") && strstr(vendor, "X.Org")) || (strstr(renderer, "Gallium ") && strstr(renderer, " on ATI ")) || (strstr(renderer, "Gallium ") && strstr(renderer, " on AMD "))) { - GPG.device = GPU_DEVICE_ATI; - GPG.driver = GPU_DRIVER_OPENSOURCE; + device = GPU_DEVICE_ATI; + driver = GPU_DRIVER_OPENSOURCE; } else if (strstr(renderer, "Nouveau") || strstr(vendor, "nouveau")) { - GPG.device = GPU_DEVICE_NVIDIA; - GPG.driver = GPU_DRIVER_OPENSOURCE; + device = GPU_DEVICE_NVIDIA; + driver = GPU_DRIVER_OPENSOURCE; } else if (strstr(vendor, "Mesa")) { - GPG.device = GPU_DEVICE_SOFTWARE; - GPG.driver = GPU_DRIVER_SOFTWARE; + device = GPU_DEVICE_SOFTWARE; + driver = GPU_DRIVER_SOFTWARE; } else if (strstr(vendor, "Microsoft")) { - GPG.device = GPU_DEVICE_SOFTWARE; - GPG.driver = GPU_DRIVER_SOFTWARE; + device = GPU_DEVICE_SOFTWARE; + driver = GPU_DRIVER_SOFTWARE; } else if (strstr(vendor, "Apple")) { /* Apple Silicon. */ - GPG.device = GPU_DEVICE_APPLE; - GPG.driver = GPU_DRIVER_OFFICIAL; + device = GPU_DEVICE_APPLE; + driver = GPU_DRIVER_OFFICIAL; } else if (strstr(renderer, "Apple Software Renderer")) { - GPG.device = GPU_DEVICE_SOFTWARE; - GPG.driver = GPU_DRIVER_SOFTWARE; + device = GPU_DEVICE_SOFTWARE; + driver = GPU_DRIVER_SOFTWARE; } else if (strstr(renderer, "llvmpipe") || strstr(renderer, "softpipe")) { - GPG.device = GPU_DEVICE_SOFTWARE; - GPG.driver = GPU_DRIVER_SOFTWARE; + device = GPU_DEVICE_SOFTWARE; + driver = GPU_DRIVER_SOFTWARE; } else { printf("Warning: Could not find a matching GPU name. Things may not behave as expected.\n"); printf("Detected OpenGL configuration:\n"); printf("Vendor: %s\n", vendor); printf("Renderer: %s\n", renderer); - GPG.device = GPU_DEVICE_ANY; - GPG.driver = GPU_DRIVER_ANY; } /* Detect support level */ if (!GLEW_VERSION_3_3) { - GPG.support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED; + support_level = GPU_SUPPORT_LEVEL_UNSUPPORTED; } else { - if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_ANY)) { + if ((device & GPU_DEVICE_INTEL) && (os & GPU_OS_WIN)) { /* Old Intel drivers with known bugs that cause material properties to crash. * Version Build 10.18.14.5067 is the latest available and appears to be working * ok with our workarounds, so excluded from this list. */ @@ -132,19 +133,19 @@ void GLBackend::platform_init() strstr(version, "Build 9.18") || strstr(version, "Build 10.18.10.3") || strstr(version, "Build 10.18.10.4") || strstr(version, "Build 10.18.10.5") || strstr(version, "Build 10.18.14.4")) { - GPG.support_level = GPU_SUPPORT_LEVEL_LIMITED; + support_level = GPU_SUPPORT_LEVEL_LIMITED; } } - if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_ANY)) { + if ((device & GPU_DEVICE_ATI) && (os & GPU_OS_UNIX)) { /* Platform seems to work when SB backend is disabled. This can be done * by adding the environment variable `R600_DEBUG=nosb`. */ if (strstr(renderer, "AMD CEDAR")) { - GPG.support_level = GPU_SUPPORT_LEVEL_LIMITED; + support_level = GPU_SUPPORT_LEVEL_LIMITED; } } - GPG.create_key(GPG.support_level, vendor, renderer, version); - GPG.create_gpu_name(vendor, renderer, version); } + + GPG.init(device, os, driver, support_level, vendor, renderer, version); } void GLBackend::platform_exit() -- cgit v1.2.3