#ifndef GPU_CONTEXT_H
#define GPU_CONTEXT_H

#include "utils.h"
#ifdef _WIN32
#include "volk.h"
#else
#include <vulkan/vulkan.h>
#endif

// ── GPU Context ────────────────────────────────────────────────────
typedef struct {
  VkInstance instance;
  VkPhysicalDevice physical_device;
  VkDevice device;
  VkQueue compute_queue;
  uint32_t compute_queue_family;
  VkCommandPool command_pool;
  VkPhysicalDeviceProperties device_props;
  VkPhysicalDeviceMemoryProperties mem_props;

  // Shader modules
  VkShaderModule compress_shader;
  VkShaderModule decompress_shader;

  // GPU info
  char device_name[256];
  uint64_t vram_size;
  uint32_t max_workgroup_size;
  bool is_initialized;
} GpuContext;

// ── Functions ──────────────────────────────────────────────────────

// Initialize Vulkan GPU context
int gpu_init(GpuContext *ctx);

// Load a SPIR-V shader module
VkShaderModule gpu_load_shader(GpuContext *ctx, const char *spv_path);

// Find memory type index matching requirements
uint32_t gpu_find_memory_type(GpuContext *ctx, uint32_t type_bits,
                              VkMemoryPropertyFlags properties);

// Create a GPU buffer
int gpu_create_buffer(GpuContext *ctx, VkDeviceSize size,
                      VkBufferUsageFlags usage,
                      VkMemoryPropertyFlags mem_props_flags, VkBuffer *buffer,
                      VkDeviceMemory *memory);

// Copy data to GPU buffer
int gpu_upload_data(GpuContext *ctx, VkDeviceMemory memory, const void *data,
                    VkDeviceSize size);

// Copy data from GPU buffer
int gpu_download_data(GpuContext *ctx, VkDeviceMemory memory, void *data,
                      VkDeviceSize size);

// Print GPU information
void gpu_print_info(const GpuContext *ctx);

// Cleanup GPU context
void gpu_cleanup(GpuContext *ctx);

#endif // GPU_CONTEXT_H
