e3c8979e8d
- cmd/fn/doctor.go - cmd/fn/main.go - cpp/apps/primitives_gallery/playground/tables/CMakeLists.txt - cpp/apps/primitives_gallery/playground/tables/data_table.cpp - cpp/apps/primitives_gallery/playground/tables/data_table_logic.cpp - cpp/apps/primitives_gallery/playground/tables/data_table_logic.h - cpp/apps/primitives_gallery/playground/tables/self_test.cpp - cpp/apps/primitives_gallery/playground/tables/tql.cpp - cpp/apps/primitives_gallery/playground/tables/viz.cpp - cpp/apps/primitives_gallery/playground/tables/viz.h - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
97 lines
3.4 KiB
C++
97 lines
3.4 KiB
C++
#include "gfx/gpu_check.h"
|
|
#include "gfx/gl_loader.h"
|
|
|
|
#include <cstring>
|
|
#include <string>
|
|
|
|
// 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(<cuda_runtime.h>)
|
|
#include <cuda_runtime.h>
|
|
#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<const char*>(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<const char*>(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<const char*>(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<const char*>(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
|