{"id":45233732,"url":"https://github.com/rusoleal/campello_gpu","last_synced_at":"2026-04-23T00:00:54.495Z","repository":{"id":298962164,"uuid":"1001675934","full_name":"rusoleal/campello_gpu","owner":"rusoleal","description":"C++ low level multiplatform graphics library.","archived":false,"fork":false,"pushed_at":"2026-04-19T07:57:13.000Z","size":872,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-19T09:30:05.410Z","etag":null,"topics":["android","directx12","graphics-rendering","ios","linux","macos","metal","vulkan","windows"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rusoleal.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-13T19:53:35.000Z","updated_at":"2026-04-19T07:53:50.000Z","dependencies_parsed_at":"2026-04-23T00:00:35.942Z","dependency_job_id":null,"html_url":"https://github.com/rusoleal/campello_gpu","commit_stats":null,"previous_names":["rusoleal/campello_gpu"],"tags_count":39,"template":false,"template_full_name":null,"purl":"pkg:github/rusoleal/campello_gpu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusoleal%2Fcampello_gpu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusoleal%2Fcampello_gpu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusoleal%2Fcampello_gpu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusoleal%2Fcampello_gpu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rusoleal","download_url":"https://codeload.github.com/rusoleal/campello_gpu/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusoleal%2Fcampello_gpu/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32159962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T17:06:48.269Z","status":"ssl_error","status_checked_at":"2026-04-22T17:06:19.037Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","directx12","graphics-rendering","ios","linux","macos","metal","vulkan","windows"],"created_at":"2026-02-20T20:42:01.211Z","updated_at":"2026-04-23T00:00:54.489Z","avatar_url":"https://github.com/rusoleal.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# campello_gpu\n\nA cross-platform GPU abstraction library (C++20) with a WebGPU-inspired API. Provides a unified interface over Metal, Vulkan, and DirectX 12 for rendering, compute and raytracing workloads.\n\n## 🚀 Part of the Campello Engine\n\nThis project is a module within the **Campello** ecosystem.\n\n👉 Main repository: https://github.com/rusoleal/campello\n\nCampello is a modular, composable game engine built as a collection of independent libraries.\nEach module is designed to work standalone, but integrates seamlessly into the engine runtime.\n\n## Platforms\n\n| OS | Engine | Status |\n|----|--------|--------|\n| android | Vulkan 1.x | Production ready |\n| macos/ios | Metal | Production ready |\n| windows | DirectX 12 | Production ready |\n| windows | DirectX 11 | Frozen |\n| windows | OpenGL | Frozen |\n| windows | Vulkan 1.x | Not started |\n| macos/ios | OpenGL | Frozen |\n| macos/ios | Vulkan 1.x | Not started |\n| android | OpenGL | Frozen |\n| linux | Vulkan 1.x | Production ready (headless) |\n| linux | OpenGL | Frozen |\n\n## Requirements\n\n- CMake 3.22.1+\n- C++20 compiler\n- Platform SDK: Metal (macOS/iOS), Vulkan (Android), DirectX 12 (Windows)\n\n## Build\n\n```bash\ncmake -B build\nmake -C build\n```\n\nCMake automatically selects the backend based on the target platform (`android.cmake`, `macos.cmake`, `windows.cmake`, etc.).\n\n## Integration\n\n### find_package (installed library)\n\n```bash\ncmake -B build -DCMAKE_INSTALL_PREFIX=/usr/local\ncmake --install build\n```\n\n```cmake\nfind_package(campello_gpu REQUIRED)\ntarget_link_libraries(your_target PRIVATE campello_gpu::campello_gpu)\n```\n\n### FetchContent\n\n```cmake\ninclude(FetchContent)\nFetchContent_Declare(\n    campello_gpu\n    GIT_REPOSITORY https://github.com/rusoleal/campello_gpu.git\n    GIT_TAG        main\n)\nFetchContent_MakeAvailable(campello_gpu)\n\ntarget_link_libraries(your_target PRIVATE campello_gpu::campello_gpu)\n```\n\n## Usage\n\nAll types are in the `systems::leal::campello_gpu` namespace.\n\n```cpp\n#include \u003ccampello_gpu/device.hpp\u003e\n\nusing namespace systems::leal::campello_gpu;\n\n// Create a device (pd is the platform window/surface handle)\nauto device = Device::createDefaultDevice(pd);\n\n// Or enumerate adapters and pick one\nauto adapters = Device::getAdapters();\nauto device = Device::createDevice(adapters[0], pd);\n\n// Query device info\nstd::string name = device-\u003egetName();\nstd::set\u003cFeature\u003e features = device-\u003egetFeatures();\nstd::string version = Device::getEngineVersion();\n```\n\n### Resource Creation\n\n```cpp\n// Buffers\nauto buffer = device-\u003ecreateBuffer(size, BufferUsage::vertex | BufferUsage::copySrc);\nauto buffer = device-\u003ecreateBuffer(size, BufferUsage::uniform, data);\n\n// Readback buffer (GPU → CPU)\nauto readbackBuffer = device-\u003ecreateBuffer(size, BufferUsage::copyDst | BufferUsage::mapRead);\n\n// Textures\nauto texture = device-\u003ecreateTexture(TextureType::_2D, PixelFormat::RGBA8Unorm,\n                                     width, height, 1, mipLevels, 1,\n                                     TextureUsage::textureBinding | TextureUsage::renderTarget);\n\n// Shaders (compiled bytecode/binary)\nauto shader = device-\u003ecreateShaderModule(buffer, size);\n```\n\n### Pipelines \u0026 Binding\n\n```cpp\n// Layout describes shader resource binding points\nauto bindGroupLayout = device-\u003ecreateBindGroupLayout(bindGroupLayoutDescriptor);\nauto pipelineLayout  = device-\u003ecreatePipelineLayout(pipelineLayoutDescriptor);\n\n// Render pipeline\nauto pipeline = device-\u003ecreateRenderPipeline(renderPipelineDescriptor);\n\n// Compute pipeline\nauto pipeline = device-\u003ecreateComputePipeline(computePipelineDescriptor);\n\n// Bind concrete resources to a layout\nauto bindGroup = device-\u003ecreateBindGroup(bindGroupDescriptor);\n```\n\n### Command Recording \u0026 Submission\n\n```cpp\nauto encoder = device-\u003ecreateCommandEncoder();\n\n// Render pass\nauto renderPass = encoder-\u003ebeginRenderPass(beginRenderPassDescriptor);\nrenderPass-\u003esetPipeline(pipeline);\nrenderPass-\u003esetVertexBuffer(0, vertexBuffer, 0);\nrenderPass-\u003esetBindGroup(0, bindGroup, {});\nrenderPass-\u003edraw(vertexCount, instanceCount, 0, 0);\nrenderPass-\u003eend();\n\n// Compute pass\nauto computePass = encoder-\u003ebeginComputePass();\ncomputePass-\u003esetPipeline(computePipeline);\ncomputePass-\u003esetBindGroup(0, bindGroup, {});\ncomputePass-\u003edispatchWorkgroups(x, y, z);\ncomputePass-\u003eend();\n\nauto commandBuffer = encoder-\u003efinish();\ndevice-\u003esubmit(commandBuffer);\n```\n\n### Ray Tracing\n\nHardware ray tracing is available when `Feature::raytracing` is reported by the device (Vulkan KHR on Android, Metal on macOS/iOS, DXR on Windows).\n\n```cpp\n#include \u003ccampello_gpu/acceleration_structure.hpp\u003e\n#include \u003ccampello_gpu/ray_tracing_pipeline.hpp\u003e\n#include \u003ccampello_gpu/ray_tracing_pass_encoder.hpp\u003e\n#include \u003ccampello_gpu/descriptors/bottom_level_acceleration_structure_descriptor.hpp\u003e\n#include \u003ccampello_gpu/descriptors/top_level_acceleration_structure_descriptor.hpp\u003e\n#include \u003ccampello_gpu/descriptors/ray_tracing_pipeline_descriptor.hpp\u003e\n#include \u003ccampello_gpu/constants/acceleration_structure_build_flag.hpp\u003e\n#include \u003ccampello_gpu/constants/acceleration_structure_geometry_type.hpp\u003e\n\n// Feature check\nauto features = device-\u003egetFeatures();\nif (!features.count(Feature::raytracing)) return; // not supported\n\n// 1. Vertex buffer for triangle geometry\nauto vertexBuffer = device-\u003ecreateBuffer(sizeof(vertices),\n    BufferUsage::accelerationStructureInput, vertices);\n\n// 2. Bottom-level acceleration structure (BLAS)\nAccelerationStructureGeometryDescriptor geoDesc{};\ngeoDesc.type         = AccelerationStructureGeometryType::triangles;\ngeoDesc.opaque       = true;\ngeoDesc.vertexBuffer = vertexBuffer;\ngeoDesc.vertexStride = sizeof(float) * 3;\ngeoDesc.vertexCount  = 3;\n\nBottomLevelAccelerationStructureDescriptor blasDesc{};\nblasDesc.geometries = { geoDesc };\nblasDesc.buildFlags = AccelerationStructureBuildFlag::preferFastTrace;\n\nauto blas   = device-\u003ecreateBottomLevelAccelerationStructure(blasDesc);\nauto scratch = device-\u003ecreateBuffer(blas-\u003egetBuildScratchSize(), BufferUsage::storage);\n\nauto encoder = device-\u003ecreateCommandEncoder();\nencoder-\u003ebuildAccelerationStructure(blas, blasDesc, scratch);\ndevice-\u003esubmit(encoder-\u003efinish());\n\n// 3. Top-level acceleration structure (TLAS)\nAccelerationStructureInstance instance{};\ninstance.blas = blas;\ninstance.mask = 0xFF;\n\nTopLevelAccelerationStructureDescriptor tlasDesc{};\ntlasDesc.instances  = { instance };\ntlasDesc.buildFlags = AccelerationStructureBuildFlag::preferFastTrace;\n\nauto tlas    = device-\u003ecreateTopLevelAccelerationStructure(tlasDesc);\nauto scratch2 = device-\u003ecreateBuffer(tlas-\u003egetBuildScratchSize(), BufferUsage::storage);\n\nencoder = device-\u003ecreateCommandEncoder();\nencoder-\u003ebuildAccelerationStructure(tlas, tlasDesc, scratch2);\ndevice-\u003esubmit(encoder-\u003efinish());\n\n// 4. Ray tracing pipeline\nRayTracingPipelineDescriptor rtDesc{};\nrtDesc.rayGeneration = { shaderModule, \"rayGenMain\" };\nrtDesc.layout        = pipelineLayout;\nrtDesc.maxRecursionDepth = 1;\n\nauto pipeline = device-\u003ecreateRayTracingPipeline(rtDesc);\n\n// 5. Dispatch rays each frame\nauto rtPass = encoder-\u003ebeginRayTracingPass();\nrtPass-\u003esetPipeline(pipeline);\nrtPass-\u003esetBindGroup(0, bindGroup, {}, 0, 0);\nrtPass-\u003etraceRays(width, height, 1);\nrtPass-\u003eend();\ndevice-\u003esubmit(encoder-\u003efinish());\n```\n\n### GPU → CPU Readback\n\nCopy texture data to a buffer and read it on the CPU:\n\n```cpp\n// Create a readback buffer\nauto readbackBuffer = device-\u003ecreateBuffer(\n    textureSize, \n    BufferUsage::copyDst | BufferUsage::mapRead);\n\n// Copy texture to buffer\nauto encoder = device-\u003ecreateCommandEncoder();\nencoder-\u003ecopyTextureToBuffer(texture, mipLevel, arrayLayer,\n                              readbackBuffer, offset, bytesPerRow);\ndevice-\u003esubmit(encoder-\u003efinish());\n\n// Read data on CPU\nstd::vector\u003cuint8_t\u003e data(textureSize);\nreadbackBuffer-\u003edownload(0, textureSize, data.data());\n```\n\nOr use the convenience method for synchronous texture readback:\n\n```cpp\n// One-liner: creates temp buffer, submits command, waits, copies data\nstd::vector\u003cuint8_t\u003e pixels(width * height * 4);\ntexture-\u003edownload(mipLevel, arrayLayer, pixels.data(), pixels.size());\n```\n\n\n### Observability \u0026 Metrics\n\nComprehensive profiling and memory monitoring across all backends:\n\n```cpp\n#include \u003ccampello_gpu/metrics.hpp\u003e\n\n// --- Resource counters (Phase 1) ---\nResourceCounters counters = device-\u003egetResourceCounters();\nstd::cout \u003c\u003c \"Buffers: \" \u003c\u003c counters.bufferCount \u003c\u003c \"\\n\";\nstd::cout \u003c\u003c \"Textures: \" \u003c\u003c counters.textureCount \u003c\u003c \"\\n\";\nstd::cout \u003c\u003c \"Render pipelines: \" \u003c\u003c counters.renderPipelineCount \u003c\u003c \"\\n\";\n\nCommandStats stats = device-\u003egetCommandStats();\nstd::cout \u003c\u003c \"Draw calls: \" \u003c\u003c stats.drawCalls \u003c\u003c \"\\n\";\nstd::cout \u003c\u003c \"Compute dispatches: \" \u003c\u003c stats.dispatchCalls \u003c\u003c \"\\n\";\n\n// Complete snapshot\nMetrics m = device-\u003egetMetrics();\n\n// --- Memory tracking (Phase 2) ---\nResourceMemoryStats mem = device-\u003egetResourceMemoryStats();\nstd::cout \u003c\u003c \"GPU memory used: \" \u003c\u003c mem.totalTrackedBytes / (1024*1024) \u003c\u003c \" MB\\n\";\nstd::cout \u003c\u003c \"  Buffers: \" \u003c\u003c mem.bufferBytes / (1024*1024) \u003c\u003c \" MB\\n\";\nstd::cout \u003c\u003c \"  Textures: \" \u003c\u003c mem.textureBytes / (1024*1024) \u003c\u003c \" MB\\n\";\nstd::cout \u003c\u003c \"Peak memory: \" \u003c\u003c mem.peakTotalBytes / (1024*1024) \u003c\u003c \" MB\\n\";\n\n// Reset peak tracking for a new measurement period\ndevice-\u003eresetPeakMemoryStats();\n\n// --- GPU timing (Phase 3) ---\nauto encoder = device-\u003ecreateCommandEncoder();\n// ... record commands ...\nauto cmdBuffer = encoder-\u003efinish();\ndevice-\u003esubmit(cmdBuffer);\n\n// Get actual GPU execution time (nanoseconds)\nuint64_t gpuTimeNs = cmdBuffer-\u003egetGPUExecutionTime();\nstd::cout \u003c\u003c \"GPU time: \" \u003c\u003c (gpuTimeNs / 1e6) \u003c\u003c \" ms\\n\";\n\n// Accumulated pass performance stats\nPassPerformanceStats perf = device-\u003egetPassPerformanceStats();\nstd::cout \u003c\u003c \"Render pass GPU time: \" \u003c\u003c perf.renderPassTimeNs / 1e6 \u003c\u003c \" ms\\n\";\n\n// --- Memory pressure management ---\n// Configure budget thresholds\nMemoryBudget budget;\nbudget.warningThresholdPercent = 75;   // 75% of available memory\nbudget.criticalThresholdPercent = 90;  // 90% of available memory\ndevice-\u003esetMemoryBudget(budget);\n\n// Register callback for pressure changes\ndevice-\u003esetMemoryPressureCallback([](MemoryPressureLevel level, const ResourceMemoryStats\u0026 stats) {\n    switch (level) {\n        case MemoryPressureLevel::Warning:\n            std::cerr \u003c\u003c \"Memory warning: \" \u003c\u003c stats.totalTrackedBytes / (1024*1024) \u003c\u003c \" MB\\n\";\n            break;\n        case MemoryPressureLevel::Critical:\n            std::cerr \u003c\u003c \"Memory critical! Consider freeing resources\\n\";\n            break;\n        default:\n            break;\n    }\n});\n\n// Check current pressure level\nMemoryPressureLevel level = device-\u003echeckMemoryPressure();\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frusoleal%2Fcampello_gpu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frusoleal%2Fcampello_gpu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frusoleal%2Fcampello_gpu/lists"}