diff --git a/source/blender/gpu/GPU_platform.h b/source/blender/gpu/GPU_platform.h index 24b1c6003d7..002d984001b 100644 --- a/source/blender/gpu/GPU_platform.h +++ b/source/blender/gpu/GPU_platform.h @@ -55,6 +55,19 @@ typedef enum eGPUSupportLevel { GPU_SUPPORT_LEVEL_UNSUPPORTED, } eGPUSupportLevel; +typedef enum GPUArchitectureType { + /* Immediate Mode Renderer (IMR). + * Typically, an IMR architecture will execute GPU work in sequence, rasterizing primitives in + * order. */ + GPU_ARCHITECTURE_IMR = 0, + + /* Tile-Based-Deferred-Renderer (TBDR). + * A TBDR architecture will typically execute the vertex stage up-front for all primitives, + * binning geometry into distinct tiled regions. Fragments will then be rasterized within + * the bounds of one tile at a time. */ + GPU_ARCHITECTURE_TBDR = 1, +} GPUArchitectureType; + #ifdef __cplusplus extern "C" { #endif @@ -74,6 +87,7 @@ 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); +GPUArchitectureType GPU_platform_architecture(void); #ifdef __cplusplus } diff --git a/source/blender/gpu/dummy/dummy_backend.hh b/source/blender/gpu/dummy/dummy_backend.hh index 72f1af8e280..3cd88bacb41 100644 --- a/source/blender/gpu/dummy/dummy_backend.hh +++ b/source/blender/gpu/dummy/dummy_backend.hh @@ -30,7 +30,8 @@ class DummyBackend : public GPUBackend { GPU_BACKEND_NONE, "Unknown", "", - ""); + "", + GPU_ARCHITECTURE_IMR); } void delete_resources() override {} void samplers_update() override {} diff --git a/source/blender/gpu/intern/gpu_platform.cc b/source/blender/gpu/intern/gpu_platform.cc index e6720912d4a..910c8742b06 100644 --- a/source/blender/gpu/intern/gpu_platform.cc +++ b/source/blender/gpu/intern/gpu_platform.cc @@ -70,7 +70,8 @@ void GPUPlatformGlobal::init(eGPUDeviceType gpu_device, eGPUBackendType backend, const char *vendor_str, const char *renderer_str, - const char *version_str) + const char *version_str, + GPUArchitectureType arch_type) { this->clear(); @@ -91,6 +92,7 @@ void GPUPlatformGlobal::init(eGPUDeviceType gpu_device, this->support_key = create_key(gpu_support_level, vendor, renderer, version); this->gpu_name = create_gpu_name(vendor, renderer, version); this->backend = backend; + this->architecture_type = arch_type; } void GPUPlatformGlobal::clear() @@ -149,6 +151,12 @@ const char *GPU_platform_gpu_name() return GPG.gpu_name; } +GPUArchitectureType GPU_platform_architecture() +{ + BLI_assert(GPG.initialized); + return GPG.architecture_type; +} + bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver) { return GPU_type_matches_ex(device, os, driver, GPU_BACKEND_ANY); diff --git a/source/blender/gpu/intern/gpu_platform_private.hh b/source/blender/gpu/intern/gpu_platform_private.hh index 9ae9010e61a..3d2efc06a22 100644 --- a/source/blender/gpu/intern/gpu_platform_private.hh +++ b/source/blender/gpu/intern/gpu_platform_private.hh @@ -25,6 +25,7 @@ class GPUPlatformGlobal { char *support_key = nullptr; char *gpu_name = nullptr; eGPUBackendType backend = GPU_BACKEND_NONE; + GPUArchitectureType architecture_type = GPU_ARCHITECTURE_IMR; public: void init(eGPUDeviceType gpu_device, @@ -34,7 +35,8 @@ class GPUPlatformGlobal { eGPUBackendType backend, const char *vendor_str, const char *renderer_str, - const char *version_str); + const char *version_str, + GPUArchitectureType arch_type); void clear(); }; diff --git a/source/blender/gpu/metal/mtl_backend.mm b/source/blender/gpu/metal/mtl_backend.mm index 28f3466c477..b02f2af80a0 100644 --- a/source/blender/gpu/metal/mtl_backend.mm +++ b/source/blender/gpu/metal/mtl_backend.mm @@ -194,6 +194,8 @@ void MTLBackend::platform_init(MTLContext *ctx) if (G.debug & G_DEBUG_GPU) { printf("METAL API - DETECTED GPU: %s\n", vendor); } + GPUArchitectureType architecture_type = (mtl_device.hasUnifiedMemory) ? GPU_ARCHITECTURE_TBDR : + GPU_ARCHITECTURE_IMR; /* macOS is the only supported platform, but check to ensure we are not building with Metal * enablement on another platform. */ @@ -240,7 +242,15 @@ void MTLBackend::platform_init(MTLContext *ctx) printf("Renderer: %s\n", renderer); } - GPG.init(device, os, driver, support_level, GPU_BACKEND_METAL, vendor, renderer, version); + GPG.init(device, + os, + driver, + support_level, + GPU_BACKEND_METAL, + vendor, + renderer, + version, + architecture_type); } void MTLBackend::platform_exit() diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index 24ee725adab..ec62f2ca59f 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -163,7 +163,15 @@ void GLBackend::platform_init() } } - GPG.init(device, os, driver, support_level, GPU_BACKEND_OPENGL, vendor, renderer, version); + GPG.init(device, + os, + driver, + support_level, + GPU_BACKEND_OPENGL, + vendor, + renderer, + version, + GPU_ARCHITECTURE_IMR); } void GLBackend::platform_exit() diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index c1eb184fb54..7d7226c4ba4 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -50,7 +50,8 @@ void VKBackend::platform_init() GPU_BACKEND_VULKAN, "", "", - ""); + "", + GPU_ARCHITECTURE_IMR); } void VKBackend::platform_init(const VKDevice &device) @@ -72,7 +73,8 @@ void VKBackend::platform_init(const VKDevice &device) GPU_BACKEND_VULKAN, vendor_name.c_str(), properties.deviceName, - driver_version.c_str()); + driver_version.c_str(), + GPU_ARCHITECTURE_IMR); } void VKBackend::detect_workarounds(VKDevice &device)