#include "gfx/gpu_check.h" #include "gfx/gl_loader.h" #include #include // CUDA runtime version via compile-time macro. // cuda_runtime.h define CUDART_VERSION como XXYYZZ (ej. 12040 para 12.4.0). // Solo se incluye si el header esta disponible; si no, cuda_runtime_version = "". #if defined(__has_include) && __has_include() #include #define FN_HAS_CUDA_RUNTIME 1 #endif namespace fn::gfx { static std::string safe_gl_string(GLenum name) { const GLubyte* s = glGetString(name); if (!s) return ""; return std::string(reinterpret_cast(s)); } static bool check_gl_version_43() { // GL_VERSION tiene formato "major.minor ..." o "OpenGL ES major.minor ..." const GLubyte* ver = glGetString(GL_VERSION); if (!ver) return false; int major = 0, minor = 0; // Saltar prefijo "OpenGL ES " si lo hay const char* p = reinterpret_cast(ver); if (std::strncmp(p, "OpenGL ES ", 10) == 0) p += 10; // sscanf con la forma "X.Y" // NOLINTNEXTLINE(cert-err34-c) std::sscanf(p, "%d.%d", &major, &minor); return (major > 4) || (major == 4 && minor >= 3); } bool gpu_check_caps(GpuCaps& out) { out = GpuCaps{}; // reset out.gl_vendor = safe_gl_string(GL_VENDOR); out.gl_renderer = safe_gl_string(GL_RENDERER); out.gl_version = safe_gl_string(GL_VERSION); if (out.gl_vendor.empty()) { // No hay contexto GL activo. return false; } // Compute shader support: GL 4.3+ o ARB_compute_shader { const GLubyte* exts = glGetString(GL_EXTENSIONS); bool has_arb = exts && std::strstr(reinterpret_cast(exts), "GL_ARB_compute_shader") != nullptr; out.has_compute_shader = check_gl_version_43() || has_arb; } // Shader storage buffer: GL 4.3+ o ARB_shader_storage_buffer_object { const GLubyte* exts = glGetString(GL_EXTENSIONS); bool has_ssbo_arb = exts && std::strstr(reinterpret_cast(exts), "GL_ARB_shader_storage_buffer_object") != nullptr; out.has_storage_buffer = check_gl_version_43() || has_ssbo_arb; } // Workgroup limits (solo si hay compute shader support) if (out.has_compute_shader) { // GL_MAX_COMPUTE_WORK_GROUP_COUNT — indexed query glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &out.max_compute_workgroup_count[0]); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &out.max_compute_workgroup_count[1]); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &out.max_compute_workgroup_count[2]); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &out.max_compute_workgroup_size[0]); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &out.max_compute_workgroup_size[1]); glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &out.max_compute_workgroup_size[2]); } // CUDA runtime version (compile-time detection) #if defined(FN_HAS_CUDA_RUNTIME) { int cuda_ver = CUDART_VERSION; // ej. 12040 para CUDA 12.4.0 int major = cuda_ver / 1000; int minor = (cuda_ver % 1000) / 10; char buf[16]; std::snprintf(buf, sizeof(buf), "%d.%d", major, minor); out.cuda_runtime_version = buf; } #else out.cuda_runtime_version = ""; #endif return true; } } // namespace fn::gfx