Skip to content

Commit

Permalink
Refactor: Add helper functions to GpuTexture2DHandle (#1900)
Browse files Browse the repository at this point in the history
* Refactor: Add helper functions to GpuTexture2DHandle

* wgpu_handle -> handle

* Rename GpuTexture2DHandle -> GpuTexture2D

* Implement AsRef, Deref, Borrow
  • Loading branch information
emilk authored Apr 18, 2023
1 parent 3623932 commit 937204c
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 75 deletions.
4 changes: 2 additions & 2 deletions crates/re_renderer/examples/2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ use re_renderer::{
ColormappedTexture, LineStripFlags, RectangleDrawData, RectangleOptions, TextureFilterMag,
TextureFilterMin, TexturedRect,
},
resource_managers::{GpuTexture2DHandle, Texture2DCreationDesc},
resource_managers::{GpuTexture2D, Texture2DCreationDesc},
view_builder::{self, Projection, TargetConfiguration, ViewBuilder},
Color32, LineStripSeriesBuilder, PointCloudBuilder, Size,
};

mod framework;

struct Render2D {
rerun_logo_texture: GpuTexture2DHandle,
rerun_logo_texture: GpuTexture2D,
rerun_logo_texture_width: u32,
rerun_logo_texture_height: u32,
}
Expand Down
4 changes: 2 additions & 2 deletions crates/re_renderer/examples/depth_cloud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use re_renderer::{
ColormappedTexture, DepthCloud, DepthCloudDepthData, DepthCloudDrawData, DepthClouds,
DrawData, GenericSkyboxDrawData, RectangleDrawData, RectangleOptions, TexturedRect,
},
resource_managers::{GpuTexture2DHandle, Texture2DCreationDesc},
resource_managers::{GpuTexture2D, Texture2DCreationDesc},
view_builder::{self, Projection, ViewBuilder},
Color32, LineStripSeriesBuilder, PointCloudBuilder, Rgba, Size,
};
Expand All @@ -44,7 +44,7 @@ enum CameraControl {
struct RenderDepthClouds {
depth: DepthTexture,
albedo: AlbedoTexture,
albedo_handle: GpuTexture2DHandle,
albedo_handle: GpuTexture2D,

scale: f32,
point_radius_from_world_depth: f32,
Expand Down
5 changes: 2 additions & 3 deletions crates/re_renderer/src/importer/gltf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ use crate::{
mesh::{Material, Mesh},
renderer::MeshInstance,
resource_managers::{
GpuMeshHandle, GpuTexture2DHandle, ResourceLifeTime, Texture2DCreationDesc,
TextureManager2D,
GpuMeshHandle, GpuTexture2D, ResourceLifeTime, Texture2DCreationDesc, TextureManager2D,
},
RenderContext, Rgba32Unmul,
};
Expand Down Expand Up @@ -126,7 +125,7 @@ fn map_format(format: gltf::image::Format) -> Option<wgpu::TextureFormat> {
fn import_mesh(
mesh: &gltf::Mesh<'_>,
buffers: &[gltf::buffer::Data],
gpu_image_handles: &[GpuTexture2DHandle],
gpu_image_handles: &[GpuTexture2D],
texture_manager: &mut TextureManager2D, //imported_materials: HashMap<usize, Material>,
) -> anyhow::Result<Mesh> {
crate::profile_function!();
Expand Down
7 changes: 3 additions & 4 deletions crates/re_renderer/src/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use smallvec::{smallvec, SmallVec};
use crate::{
allocator::create_and_fill_uniform_buffer_batch,
debug_label::DebugLabel,
resource_managers::{GpuTexture2DHandle, ResourceManagerError},
resource_managers::{GpuTexture2D, ResourceManagerError},
wgpu_resources::{
BindGroupDesc, BindGroupEntry, BufferDesc, GpuBindGroup, GpuBindGroupLayoutHandle,
GpuBuffer,
Expand Down Expand Up @@ -140,7 +140,7 @@ pub struct Material {

/// Base color texture, also known as albedo.
/// (not optional, needs to be at least a 1pix texture with a color!)
pub albedo: GpuTexture2DHandle,
pub albedo: GpuTexture2D,

/// Factor applied to the decoded albedo color.
pub albedo_multiplier: Rgba,
Expand Down Expand Up @@ -286,14 +286,13 @@ impl GpuMesh {
.iter()
.zip(uniform_buffer_bindings.into_iter())
{
let texture = ctx.texture_manager_2d.get(&material.albedo);
let bind_group = pools.bind_groups.alloc(
device,
pools,
&BindGroupDesc {
label: material.label.clone(),
entries: smallvec![
BindGroupEntry::DefaultTextureView(texture.handle),
BindGroupEntry::DefaultTextureView(material.albedo.handle()),
uniform_buffer_binding
],
layout: mesh_bind_group_layout,
Expand Down
46 changes: 16 additions & 30 deletions crates/re_renderer/src/renderer/rectangles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
depth_offset::DepthOffset,
draw_phases::{DrawPhase, OutlineMaskProcessor},
include_shader_module,
resource_managers::{GpuTexture2DHandle, ResourceManagerError},
resource_managers::{GpuTexture2D, ResourceManagerError},
view_builder::ViewBuilder,
wgpu_resources::{
BindGroupDesc, BindGroupEntry, BindGroupLayoutDesc, GpuBindGroup, GpuBindGroupLayoutHandle,
Expand Down Expand Up @@ -51,7 +51,7 @@ pub enum TextureFilterMin {
/// Describes a texture and how to map it to a color.
#[derive(Clone)]
pub struct ColormappedTexture {
pub texture: GpuTexture2DHandle,
pub texture: GpuTexture2D,

/// Min/max range of the values in the texture.
/// Used to normalize the input values (squash them to the 0-1 range).
Expand Down Expand Up @@ -84,11 +84,11 @@ pub enum ColorMapper {
/// bottom right pixel is 1.0.
///
/// The texture must have the format [`wgpu::TextureFormat::Rgba8UnormSrgb`].
Texture(GpuTexture2DHandle),
Texture(GpuTexture2D),
}

impl ColormappedTexture {
pub fn from_unorm_srgba(texture: GpuTexture2DHandle) -> Self {
pub fn from_unorm_srgba(texture: GpuTexture2D) -> Self {
Self {
texture,
range: [0.0, 1.0],
Expand Down Expand Up @@ -214,10 +214,8 @@ mod gpu_data {
}

impl UniformBuffer {
pub fn from_textured_rect(
rectangle: &super::TexturedRect,
texture_format: &wgpu::TextureFormat,
) -> Result<Self, RectangleError> {
pub fn from_textured_rect(rectangle: &super::TexturedRect) -> Result<Self, RectangleError> {
let texture_format = rectangle.colormapped_texture.texture.format();
let texture_info = texture_format.describe();

let TexturedRect {
Expand Down Expand Up @@ -245,7 +243,7 @@ mod gpu_data {

let sample_type = match texture_info.sample_type {
wgpu::TextureSampleType::Float { .. } => {
if super::is_float_filterable(texture_format) {
if super::is_float_filterable(&texture_format) {
SAMPLE_TYPE_FLOAT_FILTER
} else {
SAMPLE_TYPE_FLOAT_NOFILTER
Expand Down Expand Up @@ -351,19 +349,10 @@ impl RectangleDrawData {
});
}

let textures: Vec<_> = rectangles
.iter()
.map(|rectangle| {
ctx.texture_manager_2d
.get(&rectangle.colormapped_texture.texture)
})
.collect();

// TODO(emilk): continue on error (skipping just that rectangle)?
let uniform_buffers: Vec<_> = izip!(rectangles, &textures)
.map(|(rect, texture)| {
gpu_data::UniformBuffer::from_textured_rect(rect, &texture.creation_desc.format)
})
let uniform_buffers: Vec<_> = rectangles
.iter()
.map(gpu_data::UniformBuffer::from_textured_rect)
.try_collect()?;

let uniform_buffer_bindings = create_and_fill_uniform_buffer_batch(
Expand All @@ -373,9 +362,7 @@ impl RectangleDrawData {
);

let mut instances = Vec::with_capacity(rectangles.len());
for (rectangle, uniform_buffer, texture) in
izip!(rectangles, uniform_buffer_bindings, textures)
{
for (rectangle, uniform_buffer) in izip!(rectangles, uniform_buffer_bindings) {
let options = &rectangle.options;
let sampler = ctx.gpu_resources.samplers.get_or_create(
&ctx.device,
Expand All @@ -398,6 +385,7 @@ impl RectangleDrawData {
},
);

let texture = &rectangle.colormapped_texture.texture;
let texture_format = texture.creation_desc.format;
let texture_description = texture_format.describe();
if texture_description.required_features != Default::default() {
Expand Down Expand Up @@ -435,13 +423,11 @@ impl RectangleDrawData {
let colormap_texture = if let Some(ColorMapper::Texture(handle)) =
&rectangle.colormapped_texture.color_mapper
{
let colormap_texture = ctx.texture_manager_2d.get(handle);
if colormap_texture.creation_desc.format != wgpu::TextureFormat::Rgba8UnormSrgb {
return Err(RectangleError::UnsupportedColormapTextureFormat(
colormap_texture.creation_desc.format,
));
let format = handle.format();
if format != wgpu::TextureFormat::Rgba8UnormSrgb {
return Err(RectangleError::UnsupportedColormapTextureFormat(format));
}
colormap_texture.handle
handle.handle()
} else {
ctx.texture_manager_2d.zeroed_texture_float().handle
};
Expand Down
2 changes: 1 addition & 1 deletion crates/re_renderer/src/resource_managers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod mesh_manager;
pub use mesh_manager::{GpuMeshHandle, MeshManager};

mod texture_manager;
pub use texture_manager::{GpuTexture2DHandle, Texture2DCreationDesc, TextureManager2D};
pub use texture_manager::{GpuTexture2D, Texture2DCreationDesc, TextureManager2D};

mod resource_manager;
pub use resource_manager::{ResourceHandle, ResourceLifeTime, ResourceManagerError};
74 changes: 52 additions & 22 deletions crates/re_renderer/src/resource_managers/texture_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,59 @@ use crate::{
/// Since all textures have "long lived" behavior (no temp allocation, alive until unused),
/// there is no difference as with buffer reliant data like meshes or most contents of draw-data.
#[derive(Clone)]
pub struct GpuTexture2DHandle(GpuTexture);
pub struct GpuTexture2D(GpuTexture);

impl GpuTexture2D {
#[inline]
pub fn handle(&self) -> crate::wgpu_resources::GpuTextureHandle {
self.0.handle
}

impl GpuTexture2DHandle {
/// Width of the texture.
#[inline]
pub fn width(&self) -> u32 {
self.0.texture.width()
}

/// Height of the texture.
#[inline]
pub fn height(&self) -> u32 {
self.0.texture.height()
}

/// Width and height of the texture.
#[inline]
pub fn width_height(&self) -> [u32; 2] {
[self.width(), self.height()]
}

#[inline]
pub fn format(&self) -> wgpu::TextureFormat {
self.0.texture.format()
}
}

impl AsRef<GpuTexture> for GpuTexture2D {
#[inline(always)]
fn as_ref(&self) -> &GpuTexture {
&self.0
}
}

impl std::ops::Deref for GpuTexture2D {
type Target = GpuTexture;

#[inline(always)]
fn deref(&self) -> &GpuTexture {
&self.0
}
}

impl std::borrow::Borrow<GpuTexture> for GpuTexture2D {
#[inline(always)]
fn borrow(&self) -> &GpuTexture {
&self.0
}
}

/// Data required to create a texture 2d resource.
Expand Down Expand Up @@ -68,11 +104,11 @@ pub struct TextureManager2D {
// Long lived/short lived doesn't make sense for textures since we don't yet know a way to
// optimize for short lived textures as we do with buffer data.
//manager: ResourceManager<Texture2DHandleInner, GpuTextureHandleStrong>,
white_texture_unorm: GpuTexture2DHandle,
zeroed_texture_float: GpuTexture2DHandle,
zeroed_texture_depth: GpuTexture2DHandle,
zeroed_texture_sint: GpuTexture2DHandle,
zeroed_texture_uint: GpuTexture2DHandle,
white_texture_unorm: GpuTexture2D,
zeroed_texture_float: GpuTexture2D,
zeroed_texture_depth: GpuTexture2D,
zeroed_texture_sint: GpuTexture2D,
zeroed_texture_uint: GpuTexture2D,

// For convenience to reduce amount of times we need to pass them around
device: Arc<wgpu::Device>,
Expand All @@ -85,7 +121,7 @@ pub struct TextureManager2D {
//
// Any texture which wasn't accessed on the previous frame
// is ejected from the cache during [`begin_frame`].
texture_cache: HashMap<u64, GpuTexture2DHandle>,
texture_cache: HashMap<u64, GpuTexture2D>,
accessed_textures: HashSet<u64>,
}

Expand Down Expand Up @@ -138,7 +174,7 @@ impl TextureManager2D {
&mut self,
texture_pool: &mut GpuTexturePool,
creation_desc: &Texture2DCreationDesc<'_>,
) -> GpuTexture2DHandle {
) -> GpuTexture2D {
// TODO(andreas): Disabled the warning as we're moving towards using this texture manager for user-logged images.
// However, it's still very much a concern especially once we add mipmapping. Something we need to keep in mind.
//
Expand All @@ -165,7 +201,7 @@ impl TextureManager2D {
key: u64,
texture_pool: &mut GpuTexturePool,
texture_desc: Texture2DCreationDesc<'_>,
) -> GpuTexture2DHandle {
) -> GpuTexture2D {
enum Never {}
match self.get_or_create_with(key, texture_pool, || -> Result<_, Never> {
Ok(texture_desc)
Expand All @@ -182,7 +218,7 @@ impl TextureManager2D {
key: u64,
texture_pool: &mut GpuTexturePool,
try_create_texture_desc: impl FnOnce() -> Result<Texture2DCreationDesc<'a>, Err>,
) -> Result<GpuTexture2DHandle, Err> {
) -> Result<GpuTexture2D, Err> {
let texture_handle = match self.texture_cache.entry(key) {
std::collections::hash_map::Entry::Occupied(texture_handle) => {
texture_handle.get().clone() // already inserted
Expand All @@ -206,7 +242,7 @@ impl TextureManager2D {
}

/// Returns a single pixel white pixel with an rgba8unorm format.
pub fn white_texture_unorm_handle(&self) -> &GpuTexture2DHandle {
pub fn white_texture_unorm_handle(&self) -> &GpuTexture2D {
&self.white_texture_unorm
}

Expand Down Expand Up @@ -240,7 +276,7 @@ impl TextureManager2D {
queue: &wgpu::Queue,
texture_pool: &mut GpuTexturePool,
creation_desc: &Texture2DCreationDesc<'_>,
) -> GpuTexture2DHandle {
) -> GpuTexture2D {
crate::profile_function!();
let size = wgpu::Extent3d {
width: creation_desc.width,
Expand Down Expand Up @@ -291,13 +327,7 @@ impl TextureManager2D {

// TODO(andreas): mipmap generation

GpuTexture2DHandle(texture)
}

/// Retrieves gpu handle.
#[allow(clippy::unused_self)]
pub fn get(&self, handle: &GpuTexture2DHandle) -> GpuTexture {
handle.0.clone()
GpuTexture2D(texture)
}

pub(crate) fn begin_frame(&mut self, _frame_index: u64) {
Expand All @@ -312,9 +342,9 @@ fn create_zero_texture(
texture_pool: &mut GpuTexturePool,
device: &Arc<wgpu::Device>,
format: wgpu::TextureFormat,
) -> GpuTexture2DHandle {
) -> GpuTexture2D {
// Wgpu zeros out new textures automatically
GpuTexture2DHandle(texture_pool.alloc(
GpuTexture2D(texture_pool.alloc(
device,
&TextureDesc {
label: format!("zeroed pixel {format:?}").into(),
Expand Down
Loading

0 comments on commit 937204c

Please sign in to comment.