From 58b2d3f355cc6860f5ab159899c648c3e2986af3 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 26 Sep 2024 23:08:14 -0700 Subject: [PATCH] gles: GPU scopes support --- blade-graphics/src/gles/command.rs | 88 ++++++++++++------------------ blade-graphics/src/gles/egl.rs | 5 ++ blade-graphics/src/gles/mod.rs | 14 ++++- 3 files changed, 54 insertions(+), 53 deletions(-) diff --git a/blade-graphics/src/gles/command.rs b/blade-graphics/src/gles/command.rs index 6453c72..0e9a709 100644 --- a/blade-graphics/src/gles/command.rs +++ b/blade-graphics/src/gles/command.rs @@ -1,4 +1,4 @@ -use std::time::Duration; +use std::{str, time::Duration}; const COLOR_ATTACHMENTS: &[u32] = &[ glow::COLOR_ATTACHMENT0, @@ -82,6 +82,13 @@ impl crate::ShaderBindable for super::AccelerationStructure { impl super::CommandEncoder { fn begin_pass(&mut self, label: &str) { + if self.needs_scopes { + let start = self.string_data.len(); + self.string_data.extend_from_slice(label.as_bytes()); + self.commands.push(super::Command::PushScope { + name_range: start..self.string_data.len(), + }); + } if let Some(ref mut timing_datas) = self.timing_datas { let td = timing_datas.first_mut().unwrap(); let id = td.pass_names.len(); @@ -92,9 +99,22 @@ impl super::CommandEncoder { } } + fn pass

(&mut self, kind: super::PassKind) -> super::PassEncoder

{ + super::PassEncoder { + commands: &mut self.commands, + plain_data: &mut self.plain_data, + kind, + invalidate_attachments: Vec::new(), + pipeline: Default::default(), + limits: &self.limits, + has_scope: self.needs_scopes, + } + } + pub fn start(&mut self) { self.commands.clear(); self.plain_data.clear(); + self.string_data.clear(); self.has_present = false; } @@ -147,14 +167,7 @@ impl super::CommandEncoder { pub fn transfer(&mut self, label: &str) -> super::PassEncoder<()> { self.begin_pass(label); - super::PassEncoder { - commands: &mut self.commands, - plain_data: &mut self.plain_data, - kind: super::PassKind::Transfer, - invalidate_attachments: Vec::new(), - pipeline: Default::default(), - limits: &self.limits, - } + self.pass(super::PassKind::Transfer) } pub fn acceleration_structure(&mut self, _label: &str) -> super::PassEncoder<()> { @@ -163,14 +176,7 @@ impl super::CommandEncoder { pub fn compute(&mut self, label: &str) -> super::PassEncoder { self.begin_pass(label); - super::PassEncoder { - commands: &mut self.commands, - plain_data: &mut self.plain_data, - kind: super::PassKind::Compute, - invalidate_attachments: Vec::new(), - pipeline: Default::default(), - limits: &self.limits, - } + self.pass(super::PassKind::Compute) } pub fn render( @@ -250,14 +256,9 @@ impl super::CommandEncoder { } } - super::PassEncoder { - commands: &mut self.commands, - plain_data: &mut self.plain_data, - kind: super::PassKind::Render, - invalidate_attachments, - pipeline: Default::default(), - limits: &self.limits, - } + let mut pass = self.pass(super::PassKind::Render); + pass.invalidate_attachments = invalidate_attachments; + pass } pub fn timings(&self) -> &[(String, Duration)] { @@ -329,6 +330,9 @@ impl Drop for super::PassEncoder<'_, T> { self.commands.push(super::Command::ResetFramebuffer); } } + if self.has_scope { + self.commands.push(super::Command::PopScope); + } } } @@ -401,33 +405,6 @@ impl crate::traits::TransferEncoder for super::PassEncoder<'_, ()> { } } -#[hidden_trait::expose] -impl crate::traits::AccelerationStructureEncoder for super::PassEncoder<'_, ()> { - type AccelerationStructure = crate::AccelerationStructure; - type AccelerationStructureMesh = crate::AccelerationStructureMesh; - type BufferPiece = crate::BufferPiece; - - fn build_bottom_level( - &mut self, - _acceleration_structure: super::AccelerationStructure, - _meshes: &[crate::AccelerationStructureMesh], - _scratch_data: crate::BufferPiece, - ) { - unimplemented!() - } - - fn build_top_level( - &mut self, - _acceleration_structure: super::AccelerationStructure, - _bottom_level: &[super::AccelerationStructure], - _instance_count: u32, - _instance_data: crate::BufferPiece, - _scratch_data: crate::BufferPiece, - ) { - unimplemented!() - } -} - #[hidden_trait::expose] impl crate::traits::PipelineEncoder for super::PipelineEncoder<'_> { fn bind(&mut self, group: u32, data: &D) { @@ -1048,6 +1025,13 @@ impl super::Command { Self::QueryCounter { query } => { gl.query_counter(query, glow::TIMESTAMP); } + Self::PushScope { ref name_range } => { + let name = str::from_utf8(&ec.string_data[name_range.clone()]).unwrap(); + gl.push_debug_group(glow::DEBUG_SOURCE_APPLICATION, super::DEBUG_ID, name); + } + Self::PopScope => { + gl.pop_debug_group(); + } } } } diff --git a/blade-graphics/src/gles/egl.rs b/blade-graphics/src/gles/egl.rs index d7f76c4..3bf9017 100644 --- a/blade-graphics/src/gles/egl.rs +++ b/blade-graphics/src/gles/egl.rs @@ -826,6 +826,11 @@ impl EglContext { ); let toggles = super::Toggles { + scoping: desc.capture + && (gl.supports_debug() || { + log::warn!("Scoping is not supported"); + false + }), timing: desc.timing && (extensions.contains("GL_EXT_disjoint_timer_query") || { log::warn!("Timing is not supported"); diff --git a/blade-graphics/src/gles/mod.rs b/blade-graphics/src/gles/mod.rs index a3cc95d..d3f6dca 100644 --- a/blade-graphics/src/gles/mod.rs +++ b/blade-graphics/src/gles/mod.rs @@ -5,7 +5,7 @@ mod pipeline; mod platform; mod resource; -use std::{marker::PhantomData, ops::Range, time::Duration}; +use std::{marker::PhantomData, mem, ops::Range, time::Duration}; type BindTarget = u32; const DEBUG_ID: u32 = 0; @@ -27,6 +27,7 @@ struct Limits { #[derive(Debug, Default)] struct Toggles { + scoping: bool, timing: bool, } @@ -349,6 +350,10 @@ enum Command { QueryCounter { query: glow::Query, }, + PushScope { + name_range: Range, + }, + PopScope, } struct TimingData { @@ -360,6 +365,8 @@ pub struct CommandEncoder { name: String, commands: Vec, plain_data: Vec, + string_data: Vec, + needs_scopes: bool, has_present: bool, limits: Limits, timing_datas: Option>, @@ -380,6 +387,7 @@ pub struct PassEncoder<'a, P> { invalidate_attachments: Vec, pipeline: PhantomData

, limits: &'a Limits, + has_scope: bool, } pub type ComputeCommandEncoder<'a> = PassEncoder<'a, ComputePipeline>; @@ -420,6 +428,7 @@ pub struct SyncPoint { struct ExecutionContext { framebuf: glow::Framebuffer, plain_buffer: glow::Buffer, + string_data: Box<[u8]>, } impl Context { @@ -463,6 +472,8 @@ impl crate::traits::CommandDevice for Context { name: desc.name.to_string(), commands: Vec::new(), plain_data: Vec::new(), + string_data: Vec::new(), + needs_scopes: self.toggles.scoping, has_present: false, limits: self.limits.clone(), timing_datas, @@ -510,6 +521,7 @@ impl crate::traits::CommandDevice for Context { ExecutionContext { framebuf, plain_buffer, + string_data: mem::take(&mut encoder.string_data).into_boxed_slice(), } }; for command in encoder.commands.iter() {