name for gpu buffers

This commit is contained in:
Dmitry Stepanov
2025-06-14 19:38:43 +03:00
parent 29cb0dfb11
commit 4dda250466
17 changed files with 132 additions and 70 deletions
+1
View File
@@ -55,6 +55,7 @@ impl OverlayRenderPass {
pub fn new(server: &dyn GraphicsServer) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(Self {
quad: GpuGeometryBuffer::from_surface_data(
"Quad",
&SurfaceData::make_collapsed_xy_quad(),
BufferUsage::StaticDraw,
server,
+14 -8
View File
@@ -20,6 +20,7 @@
use crate::server::GlGraphicsServer;
use crate::ToGlConstant;
use fyrox_graphics::buffer::GpuBufferDescriptor;
use fyrox_graphics::{
buffer::{BufferKind, BufferUsage, GpuBufferTrait},
error::FrameworkError,
@@ -66,25 +67,30 @@ pub struct GlBuffer {
impl GlBuffer {
pub fn new(
server: &GlGraphicsServer,
size_bytes: usize,
kind: BufferKind,
usage: BufferUsage,
desc: GpuBufferDescriptor,
) -> Result<Self, FrameworkError> {
let GpuBufferDescriptor {
name,
size,
kind,
usage,
} = desc;
unsafe {
let gl_kind = kind.into_gl();
let gl_usage = usage.into_gl();
let id = server.gl.create_buffer()?;
server.gl.bind_buffer(gl_kind, Some(id));
if size_bytes > 0 {
server
.gl
.buffer_data_size(gl_kind, size_bytes as i32, gl_usage);
if server.gl.supports_debug() {
server.gl.object_label(glow::BUFFER, id.0.get(), Some(name));
}
if size > 0 {
server.gl.buffer_data_size(gl_kind, size as i32, gl_usage);
}
server.gl.bind_buffer(gl_kind, None);
Ok(Self {
state: server.weak(),
id,
size: Cell::new(size_bytes),
size: Cell::new(size),
kind,
usage,
})
+29 -6
View File
@@ -19,12 +19,13 @@
// SOFTWARE.
use crate::{buffer::GlBuffer, server::GlGraphicsServer, ToGlConstant};
use fyrox_graphics::buffer::GpuBufferDescriptor;
use fyrox_graphics::{
buffer::{BufferKind, GpuBufferTrait},
core::{array_as_u8_slice, math::TriangleDefinition},
error::FrameworkError,
geometry_buffer::{
AttributeKind, ElementsDescriptor, GeometryBufferDescriptor, GpuGeometryBufferTrait,
AttributeKind, ElementsDescriptor, GpuGeometryBufferDescriptor, GpuGeometryBufferTrait,
},
ElementKind,
};
@@ -56,13 +57,28 @@ pub struct GlGeometryBuffer {
impl GlGeometryBuffer {
pub fn new(
server: &GlGraphicsServer,
desc: GeometryBufferDescriptor,
desc: GpuGeometryBufferDescriptor,
) -> Result<Self, FrameworkError> {
let vao = unsafe { server.gl.create_vertex_array()? };
server.set_vertex_array_object(Some(vao));
if server.gl.supports_debug() {
unsafe {
server
.gl
.object_label(glow::VERTEX_ARRAY, vao.0.get(), Some(desc.name));
}
}
let element_buffer = GlBuffer::new(server, 0, BufferKind::Index, desc.usage)?;
let element_buffer = GlBuffer::new(
server,
GpuBufferDescriptor {
name: &format!("{}ElementBuffer", desc.name),
size: 0,
kind: BufferKind::Index,
usage: desc.usage,
},
)?;
let (element_count, data) = match desc.elements {
ElementsDescriptor::Triangles(triangles) => {
@@ -75,12 +91,19 @@ impl GlGeometryBuffer {
element_buffer.write_data(data)?;
let mut buffers = Vec::new();
for buffer in desc.buffers {
for (i, buffer) in desc.buffers.iter().enumerate() {
unsafe {
let data_size = buffer.data.bytes.map(|bytes| bytes.len()).unwrap_or(0);
let native_buffer =
GlBuffer::new(server, data_size, BufferKind::Vertex, buffer.usage)?;
let native_buffer = GlBuffer::new(
server,
GpuBufferDescriptor {
name: &format!("{}VertexBuffer{i}", desc.name),
size: data_size,
kind: BufferKind::Vertex,
usage: buffer.usage,
},
)?;
if let Some(data) = buffer.data.bytes {
native_buffer.write_data(data)?;
+8 -3
View File
@@ -20,6 +20,7 @@
use crate::texture::PixelDescriptor;
use crate::{buffer::GlBuffer, framebuffer::GlFrameBuffer, server::GlGraphicsServer, ToGlConstant};
use fyrox_graphics::buffer::GpuBufferDescriptor;
use fyrox_graphics::{
buffer::{BufferKind, BufferUsage, GpuBufferTrait},
core::{algebra::Vector2, math::Rect},
@@ -48,15 +49,19 @@ pub struct GlAsyncReadBuffer {
impl GlAsyncReadBuffer {
pub fn new(
server: &GlGraphicsServer,
name: &str,
pixel_size: usize,
pixel_count: usize,
) -> Result<Self, FrameworkError> {
let size_bytes = pixel_count * pixel_size;
let buffer = GlBuffer::new(
server,
size_bytes,
BufferKind::PixelRead,
BufferUsage::StreamRead,
GpuBufferDescriptor {
name,
size: size_bytes,
kind: BufferKind::PixelRead,
usage: BufferUsage::StreamRead,
},
)?;
Ok(Self {
server: server.weak(),
+8 -16
View File
@@ -18,8 +18,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
use crate::buffer::GlBuffer;
use crate::{
buffer::GlBuffer,
framebuffer::GlFrameBuffer,
geometry_buffer::GlGeometryBuffer,
program::{GlProgram, GlShader},
@@ -30,11 +30,11 @@ use crate::{
ToGlConstant,
};
use fyrox_graphics::{
buffer::{BufferKind, BufferUsage, GpuBuffer},
buffer::{GpuBuffer, GpuBufferDescriptor},
core::{color::Color, log::Log, math::Rect},
error::FrameworkError,
framebuffer::{Attachment, GpuFrameBuffer},
geometry_buffer::{GeometryBufferDescriptor, GpuGeometryBuffer},
geometry_buffer::{GpuGeometryBuffer, GpuGeometryBufferDescriptor},
gpu_program::{GpuProgram, GpuShader, ShaderKind, ShaderResourceDefinition},
gpu_texture::{GpuTexture, GpuTextureDescriptor},
query::GpuQuery,
@@ -1001,18 +1001,8 @@ impl GlGraphicsServer {
}
impl GraphicsServer for GlGraphicsServer {
fn create_buffer(
&self,
size: usize,
buffer_kind: BufferKind,
buffer_usage: BufferUsage,
) -> Result<GpuBuffer, FrameworkError> {
Ok(GpuBuffer(Rc::new(GlBuffer::new(
self,
size,
buffer_kind,
buffer_usage,
)?)))
fn create_buffer(&self, desc: GpuBufferDescriptor) -> Result<GpuBuffer, FrameworkError> {
Ok(GpuBuffer(Rc::new(GlBuffer::new(self, desc)?)))
}
fn create_texture(&self, desc: GpuTextureDescriptor) -> Result<GpuTexture, FrameworkError> {
@@ -1083,11 +1073,13 @@ impl GraphicsServer for GlGraphicsServer {
fn create_async_read_buffer(
&self,
name: &str,
pixel_size: usize,
pixel_count: usize,
) -> Result<GpuAsyncReadBuffer, FrameworkError> {
Ok(GpuAsyncReadBuffer(Rc::new(GlAsyncReadBuffer::new(
self,
name,
pixel_size,
pixel_count,
)?)))
@@ -1095,7 +1087,7 @@ impl GraphicsServer for GlGraphicsServer {
fn create_geometry_buffer(
&self,
desc: GeometryBufferDescriptor,
desc: GpuGeometryBufferDescriptor,
) -> Result<GpuGeometryBuffer, FrameworkError> {
Ok(GpuGeometryBuffer(Rc::new(GlGeometryBuffer::new(
self, desc,
+7
View File
@@ -26,6 +26,13 @@ use crate::error::FrameworkError;
use bytemuck::Pod;
use fyrox_core::{array_as_u8_slice, array_as_u8_slice_mut, define_as_any_trait};
pub struct GpuBufferDescriptor<'a> {
pub name: &'a str,
pub size: usize,
pub kind: BufferKind,
pub usage: BufferUsage,
}
/// GPU buffer kind.
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum BufferKind {
+5 -3
View File
@@ -127,7 +127,9 @@ impl ElementsDescriptor<'_> {
/// Descriptor of the geometry buffer. It essentially binds multiple vertex buffers and one element
/// buffer.
pub struct GeometryBufferDescriptor<'a> {
pub struct GpuGeometryBufferDescriptor<'a> {
/// Name of the geometry buffer. Used only for debugging purposes.
pub name: &'a str,
/// Vertex buffers of the buffer. There must be at least one vertex buffer.
pub buffers: &'a [VertexBufferDescriptor<'a>],
/// Usage of the geometry buffer. See [`BufferUsage`] docs for more info.
@@ -152,7 +154,7 @@ define_as_any_trait!(GpuGeometryBufferAsAny => GpuGeometryBufferTrait);
/// error::FrameworkError,
/// geometry_buffer::{
/// AttributeDefinition, AttributeKind, ElementsDescriptor, GpuGeometryBuffer,
/// GeometryBufferDescriptor, VertexBufferData, VertexBufferDescriptor,
/// GpuGeometryBufferDescriptor, VertexBufferData, VertexBufferDescriptor,
/// },
/// server::GraphicsServer,
/// };
@@ -183,7 +185,7 @@ define_as_any_trait!(GpuGeometryBufferAsAny => GpuGeometryBufferTrait);
///
/// let triangles = [TriangleDefinition([0, 1, 2])];
///
/// server.create_geometry_buffer(GeometryBufferDescriptor {
/// server.create_geometry_buffer(GpuGeometryBufferDescriptor {
/// buffers: &[VertexBufferDescriptor {
/// usage: BufferUsage::StaticDraw,
/// attributes: &[AttributeDefinition {
+5 -9
View File
@@ -24,10 +24,10 @@
//! supported by the engine.
use crate::{
buffer::{BufferKind, BufferUsage, GpuBuffer},
buffer::{GpuBuffer, GpuBufferDescriptor},
error::FrameworkError,
framebuffer::{Attachment, GpuFrameBuffer},
geometry_buffer::{GeometryBufferDescriptor, GpuGeometryBuffer},
geometry_buffer::{GpuGeometryBuffer, GpuGeometryBufferDescriptor},
gpu_program::{GpuProgram, GpuShader, ShaderKind, ShaderResourceDefinition},
gpu_texture::{GpuTexture, GpuTextureDescriptor, GpuTextureKind, PixelKind},
query::GpuQuery,
@@ -65,12 +65,7 @@ define_as_any_trait!(GraphicsServerAsAny => GraphicsServer);
pub trait GraphicsServer: GraphicsServerAsAny {
/// Creates a GPU buffer with the given size and kind. Usage is a hint to the video driver
/// that allows to perform some potential performance optimizations.
fn create_buffer(
&self,
size: usize,
buffer_kind: BufferKind,
buffer_usage: BufferUsage,
) -> Result<GpuBuffer, FrameworkError>;
fn create_buffer(&self, desc: GpuBufferDescriptor) -> Result<GpuBuffer, FrameworkError>;
/// Creates a new GPU texture using the given descriptor.
fn create_texture(&self, desc: GpuTextureDescriptor) -> Result<GpuTexture, FrameworkError>;
@@ -123,6 +118,7 @@ pub trait GraphicsServer: GraphicsServerAsAny {
/// used to read rendering result from GPU to CPU memory and save the result to disk.
fn create_async_read_buffer(
&self,
name: &str,
pixel_size: usize,
pixel_count: usize,
) -> Result<GpuAsyncReadBuffer, FrameworkError>;
@@ -132,7 +128,7 @@ pub trait GraphicsServer: GraphicsServerAsAny {
/// GPU.
fn create_geometry_buffer(
&self,
desc: GeometryBufferDescriptor,
desc: GpuGeometryBufferDescriptor,
) -> Result<GpuGeometryBuffer, FrameworkError>;
/// Creates a weak reference to the shared graphics server.
+8 -2
View File
@@ -45,8 +45,14 @@ fn create_geometry_buffer(
data: &SurfaceData,
server: &dyn GraphicsServer,
) -> Result<SurfaceRenderData, FrameworkError> {
let geometry_buffer =
GpuGeometryBuffer::from_surface_data(data, BufferUsage::StaticDraw, server)?;
let geometry_buffer = GpuGeometryBuffer::from_surface_data(
// TODO: It might be worth to add more informative name using a combination of the name of
// the parent scene node, surface index.
"GeometryBuffer",
data,
BufferUsage::StaticDraw,
server,
)?;
Ok(SurfaceRenderData {
buffer: geometry_buffer,
+13 -8
View File
@@ -29,7 +29,7 @@ use crate::renderer::framework::{
uniform::{ByteStorage, DynamicUniformBuffer, UniformBuffer},
};
use fxhash::FxHashMap;
use fyrox_graphics::buffer::GpuBuffer;
use fyrox_graphics::buffer::{GpuBuffer, GpuBufferDescriptor};
use fyrox_graphics::server::SharedGraphicsServer;
use std::cell::RefCell;
@@ -54,8 +54,12 @@ impl UniformBufferSet {
self.free += 1;
Ok(buffer.clone())
} else {
let buffer =
server.create_buffer(size, BufferKind::Uniform, BufferUsage::StreamCopy)?;
let buffer = server.create_buffer(GpuBufferDescriptor {
name: &format!("UniformBuffer{}", self.buffers.len()),
size,
kind: BufferKind::Uniform,
usage: BufferUsage::StreamCopy,
})?;
self.buffers.push(buffer);
self.free = self.buffers.len();
Ok(self.buffers.last().unwrap().clone())
@@ -203,11 +207,12 @@ impl UniformMemoryAllocator {
pub fn upload(&mut self, server: &dyn GraphicsServer) -> Result<(), FrameworkError> {
if self.gpu_buffers.len() < self.pages.len() {
for _ in 0..(self.pages.len() - self.gpu_buffers.len()) {
let buffer = server.create_buffer(
self.max_uniform_buffer_size,
BufferKind::Uniform,
BufferUsage::StreamCopy,
)?;
let buffer = server.create_buffer(GpuBufferDescriptor {
name: &format!("UniformMemoryPage{}", self.gpu_buffers.len()),
size: self.max_uniform_buffer_size,
kind: BufferKind::Uniform,
usage: BufferUsage::StreamCopy,
})?;
self.gpu_buffers.push(buffer);
}
}
+4 -3
View File
@@ -40,8 +40,8 @@ use crate::{
error::FrameworkError,
framebuffer::GpuFrameBuffer,
geometry_buffer::{
AttributeDefinition, AttributeKind, ElementsDescriptor, GeometryBufferDescriptor,
GpuGeometryBuffer, VertexBufferData, VertexBufferDescriptor,
AttributeDefinition, AttributeKind, ElementsDescriptor, GpuGeometryBuffer,
GpuGeometryBufferDescriptor, VertexBufferData, VertexBufferDescriptor,
},
server::GraphicsServer,
},
@@ -84,7 +84,8 @@ pub fn draw_rect(rect: &Rect<f32>, lines: &mut Vec<Line>, color: Color) {
impl DebugRenderer {
pub(crate) fn new(server: &dyn GraphicsServer) -> Result<Self, FrameworkError> {
let desc = GeometryBufferDescriptor {
let desc = GpuGeometryBufferDescriptor {
name: "DebugGeometryBuffer",
elements: ElementsDescriptor::Lines(&[]),
buffers: &[VertexBufferDescriptor {
usage: BufferUsage::DynamicDraw,
+5 -2
View File
@@ -25,7 +25,7 @@ use crate::{
buffer::BufferUsage,
error::FrameworkError,
geometry_buffer::{
AttributeDefinition, AttributeKind, GeometryBufferDescriptor, VertexBufferData,
AttributeDefinition, AttributeKind, GpuGeometryBufferDescriptor, VertexBufferData,
VertexBufferDescriptor,
},
server::GraphicsServer,
@@ -39,6 +39,7 @@ pub use fyrox_graphics::*;
pub trait GeometryBufferExt {
/// Creates [`GpuGeometryBuffer`] from [`SurfaceData`].
fn from_surface_data(
name: &str,
data: &SurfaceData,
usage: BufferUsage,
server: &dyn GraphicsServer,
@@ -47,6 +48,7 @@ pub trait GeometryBufferExt {
impl GeometryBufferExt for GpuGeometryBuffer {
fn from_surface_data(
name: &str,
data: &SurfaceData,
usage: BufferUsage,
server: &dyn GraphicsServer,
@@ -69,7 +71,8 @@ impl GeometryBufferExt for GpuGeometryBuffer {
})
.collect::<Vec<_>>();
let geometry_buffer_desc = GeometryBufferDescriptor {
let geometry_buffer_desc = GpuGeometryBufferDescriptor {
name,
buffers: &[VertexBufferDescriptor {
usage,
attributes: &attributes,
+3
View File
@@ -140,6 +140,7 @@ impl DeferredLightRenderer {
Ok(Self {
skybox: GpuGeometryBuffer::from_surface_data(
"SkyBox",
&SurfaceData::new(
VertexBuffer::new(vertices.len(), vertices).unwrap(),
TriangleBuffer::new(vec![
@@ -161,11 +162,13 @@ impl DeferredLightRenderer {
server,
)?,
sphere: GpuGeometryBuffer::from_surface_data(
"Sphere",
&SurfaceData::make_sphere(10, 10, 1.0, &Matrix4::identity()),
BufferUsage::StaticDraw,
server,
)?,
cone: GpuGeometryBuffer::from_surface_data(
"Cone",
&SurfaceData::make_cone(
16,
0.5,
+2
View File
@@ -51,6 +51,7 @@ impl LightVolumeRenderer {
pub fn new(server: &dyn GraphicsServer) -> Result<Self, FrameworkError> {
Ok(Self {
cone: GpuGeometryBuffer::from_surface_data(
"Cone",
&SurfaceData::make_cone(
16,
1.0,
@@ -61,6 +62,7 @@ impl LightVolumeRenderer {
server,
)?,
sphere: GpuGeometryBuffer::from_surface_data(
"Sphere",
&SurfaceData::make_sphere(8, 8, 1.0, &Matrix4::identity()),
BufferUsage::StaticDraw,
server,
@@ -62,7 +62,11 @@ impl VisibilityBufferOptimizer {
Ok(Self {
framebuffer: server
.create_frame_buffer(None, vec![Attachment::color(optimized_visibility_buffer)])?,
pixel_buffer: server.create_async_read_buffer(size_of::<u32>(), w_tiles * h_tiles)?,
pixel_buffer: server.create_async_read_buffer(
"OcclusionReadBuffer",
size_of::<u32>(),
w_tiles * h_tiles,
)?,
w_tiles,
h_tiles,
})
+9 -5
View File
@@ -25,6 +25,7 @@ use crate::{
renderer::{cache::shader::RenderPassContainer, framework::GeometryBufferExt},
scene::mesh::surface::SurfaceData,
};
use fyrox_graphics::buffer::GpuBufferDescriptor;
use fyrox_graphics::{
buffer::{BufferKind, BufferUsage, GpuBuffer},
error::FrameworkError,
@@ -282,11 +283,12 @@ impl RendererResources {
..Default::default()
})?,
bone_matrices_stub_uniform_buffer: {
let buffer = server.create_buffer(
ShaderDefinition::MAX_BONE_MATRICES * size_of::<Matrix4<f32>>(),
BufferKind::Uniform,
BufferUsage::StaticDraw,
)?;
let buffer = server.create_buffer(GpuBufferDescriptor {
name: "BoneMatricesStubBuffer",
size: ShaderDefinition::MAX_BONE_MATRICES * size_of::<Matrix4<f32>>(),
kind: BufferKind::Uniform,
usage: BufferUsage::StaticDraw,
})?;
const SIZE: usize = ShaderDefinition::MAX_BONE_MATRICES * size_of::<Matrix4<f32>>();
let zeros = [0.0; SIZE];
buffer.write_data(array_as_u8_slice(&zeros))?;
@@ -327,11 +329,13 @@ impl RendererResources {
..Default::default()
})?,
quad: GpuGeometryBuffer::from_surface_data(
"UnitQuad",
&SurfaceData::make_unit_xy_quad(),
BufferUsage::StaticDraw,
server,
)?,
cube: GpuGeometryBuffer::from_surface_data(
"UnitCube",
&SurfaceData::make_cube(Matrix4::identity()),
BufferUsage::StaticDraw,
server,
+6 -4
View File
@@ -45,8 +45,8 @@ use crate::{
error::FrameworkError,
framebuffer::GpuFrameBuffer,
geometry_buffer::{
AttributeDefinition, AttributeKind, ElementsDescriptor, GeometryBufferDescriptor,
GpuGeometryBuffer, VertexBufferData, VertexBufferDescriptor,
AttributeDefinition, AttributeKind, ElementsDescriptor, GpuGeometryBuffer,
GpuGeometryBufferDescriptor, VertexBufferData, VertexBufferDescriptor,
},
server::GraphicsServer,
BlendFactor, BlendFunc, BlendParameters, ColorMask, CompareFunc, DrawParameters,
@@ -212,7 +212,8 @@ fn write_uniform_blocks(
impl UiRenderer {
pub(in crate::renderer) fn new(server: &dyn GraphicsServer) -> Result<Self, FrameworkError> {
let geometry_buffer_desc = GeometryBufferDescriptor {
let geometry_buffer_desc = GpuGeometryBufferDescriptor {
name: "UiGeometryBuffer",
elements: ElementsDescriptor::Triangles(&[]),
buffers: &[VertexBufferDescriptor {
usage: BufferUsage::DynamicDraw,
@@ -244,7 +245,8 @@ impl UiRenderer {
usage: BufferUsage::DynamicDraw,
};
let clipping_geometry_buffer_desc = GeometryBufferDescriptor {
let clipping_geometry_buffer_desc = GpuGeometryBufferDescriptor {
name: "UiClippingGeometryBuffer",
elements: ElementsDescriptor::Triangles(&[]),
buffers: &[VertexBufferDescriptor {
usage: BufferUsage::DynamicDraw,