Skip to main content

oxihuman_viewer/
gpu_buffer.rs

1// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
2// SPDX-License-Identifier: Apache-2.0
3
4#![allow(dead_code)]
5//! GPU buffer abstraction for vertex/index/uniform data.
6
7#[allow(dead_code)]
8#[derive(Clone, Debug, PartialEq)]
9pub enum BufferUsage {
10    Vertex,
11    Index,
12    Uniform,
13    Storage,
14}
15
16#[allow(dead_code)]
17#[derive(Clone, Debug)]
18pub struct GpuBuffer {
19    data: Vec<u8>,
20    usage: BufferUsage,
21    mapped: bool,
22}
23
24#[allow(dead_code)]
25pub fn new_gpu_buffer(usage: BufferUsage, capacity: usize) -> GpuBuffer {
26    GpuBuffer {
27        data: vec![0_u8; capacity],
28        usage,
29        mapped: false,
30    }
31}
32
33#[allow(dead_code)]
34pub fn buffer_write(buf: &mut GpuBuffer, offset: usize, data: &[u8]) -> bool {
35    if offset + data.len() > buf.data.len() {
36        return false;
37    }
38    buf.data[offset..offset + data.len()].copy_from_slice(data);
39    true
40}
41
42#[allow(dead_code)]
43pub fn buffer_read(buf: &GpuBuffer, offset: usize, len: usize) -> Option<&[u8]> {
44    if offset + len > buf.data.len() {
45        return None;
46    }
47    Some(&buf.data[offset..offset + len])
48}
49
50#[allow(dead_code)]
51pub fn buffer_size_gpu(buf: &GpuBuffer) -> usize {
52    buf.data.len()
53}
54
55#[allow(dead_code)]
56pub fn buffer_usage(buf: &GpuBuffer) -> &BufferUsage {
57    &buf.usage
58}
59
60#[allow(dead_code)]
61pub fn buffer_is_mapped(buf: &GpuBuffer) -> bool {
62    buf.mapped
63}
64
65#[allow(dead_code)]
66pub fn buffer_clear(buf: &mut GpuBuffer) {
67    for b in &mut buf.data {
68        *b = 0;
69    }
70}
71
72#[allow(dead_code)]
73pub fn buffer_to_json(buf: &GpuBuffer) -> String {
74    let usage = match &buf.usage {
75        BufferUsage::Vertex => "vertex",
76        BufferUsage::Index => "index",
77        BufferUsage::Uniform => "uniform",
78        BufferUsage::Storage => "storage",
79    };
80    format!(
81        "{{\"usage\":\"{}\",\"size\":{},\"mapped\":{}}}",
82        usage,
83        buf.data.len(),
84        buf.mapped
85    )
86}
87
88#[cfg(test)]
89mod tests {
90    use super::*;
91
92    #[test]
93    fn test_new_gpu_buffer() {
94        let b = new_gpu_buffer(BufferUsage::Vertex, 1024);
95        assert_eq!(buffer_size_gpu(&b), 1024);
96    }
97
98    #[test]
99    fn test_buffer_write() {
100        let mut b = new_gpu_buffer(BufferUsage::Vertex, 16);
101        assert!(buffer_write(&mut b, 0, &[1, 2, 3, 4]));
102    }
103
104    #[test]
105    fn test_buffer_write_overflow() {
106        let mut b = new_gpu_buffer(BufferUsage::Vertex, 4);
107        assert!(!buffer_write(&mut b, 0, &[0; 8]));
108    }
109
110    #[test]
111    fn test_buffer_read() {
112        let mut b = new_gpu_buffer(BufferUsage::Index, 16);
113        buffer_write(&mut b, 0, &[10, 20, 30]);
114        let data = buffer_read(&b, 0, 3).expect("should succeed");
115        assert_eq!(data, &[10, 20, 30]);
116    }
117
118    #[test]
119    fn test_buffer_read_overflow() {
120        let b = new_gpu_buffer(BufferUsage::Vertex, 4);
121        assert!(buffer_read(&b, 0, 8).is_none());
122    }
123
124    #[test]
125    fn test_buffer_usage() {
126        let b = new_gpu_buffer(BufferUsage::Uniform, 64);
127        assert_eq!(*buffer_usage(&b), BufferUsage::Uniform);
128    }
129
130    #[test]
131    fn test_buffer_is_mapped() {
132        let b = new_gpu_buffer(BufferUsage::Storage, 128);
133        assert!(!buffer_is_mapped(&b));
134    }
135
136    #[test]
137    fn test_buffer_clear() {
138        let mut b = new_gpu_buffer(BufferUsage::Vertex, 8);
139        buffer_write(&mut b, 0, &[1, 2, 3, 4, 5, 6, 7, 8]);
140        buffer_clear(&mut b);
141        let data = buffer_read(&b, 0, 4).expect("should succeed");
142        assert_eq!(data, &[0, 0, 0, 0]);
143    }
144
145    #[test]
146    fn test_buffer_to_json() {
147        let b = new_gpu_buffer(BufferUsage::Vertex, 256);
148        let json = buffer_to_json(&b);
149        assert!(json.contains("\"usage\":\"vertex\""));
150    }
151
152    #[test]
153    fn test_storage_buffer() {
154        let b = new_gpu_buffer(BufferUsage::Storage, 512);
155        assert_eq!(*buffer_usage(&b), BufferUsage::Storage);
156        assert_eq!(buffer_size_gpu(&b), 512);
157    }
158}