From 696ed710900d5a9751475767eb165eb0e871d77f Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sun, 26 Feb 2023 20:44:29 +0300 Subject: [PATCH] Add gfx memory usage utilities --- libs/gfx/include/psemek/gfx/buffer.hpp | 6 ++ libs/gfx/include/psemek/gfx/mesh.hpp | 5 ++ libs/gfx/include/psemek/gfx/pixel.hpp | 2 + libs/gfx/include/psemek/gfx/texture.hpp | 14 +++++ libs/gfx/source/pixel.cpp | 76 +++++++++++++++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 libs/gfx/source/pixel.cpp diff --git a/libs/gfx/include/psemek/gfx/buffer.hpp b/libs/gfx/include/psemek/gfx/buffer.hpp index 45ea4959..a0daad75 100644 --- a/libs/gfx/include/psemek/gfx/buffer.hpp +++ b/libs/gfx/include/psemek/gfx/buffer.hpp @@ -180,4 +180,10 @@ namespace psemek::gfx using buffer = basic_buffer; using uniform_buffer = basic_buffer; + template + std::size_t memory_usage(basic_buffer const & buffer) + { + return buffer.size(); + } + } diff --git a/libs/gfx/include/psemek/gfx/mesh.hpp b/libs/gfx/include/psemek/gfx/mesh.hpp index 4fdfec7d..f7658335 100644 --- a/libs/gfx/include/psemek/gfx/mesh.hpp +++ b/libs/gfx/include/psemek/gfx/mesh.hpp @@ -363,4 +363,9 @@ namespace psemek::gfx imported_mesh load_mesh(std::string_view data); + inline std::size_t memory_usage(mesh const & mesh) + { + return memory_usage(mesh.vertex_buffer()) + memory_usage(mesh.index_buffer()) + memory_usage(mesh.instance_buffer()); + } + } diff --git a/libs/gfx/include/psemek/gfx/pixel.hpp b/libs/gfx/include/psemek/gfx/pixel.hpp index 07629a79..2c26b4c2 100644 --- a/libs/gfx/include/psemek/gfx/pixel.hpp +++ b/libs/gfx/include/psemek/gfx/pixel.hpp @@ -453,4 +453,6 @@ namespace psemek::gfx static constexpr GLenum type = gl::UNSIGNED_BYTE; }; + std::size_t pixel_size(GLint internal_format); + } diff --git a/libs/gfx/include/psemek/gfx/texture.hpp b/libs/gfx/include/psemek/gfx/texture.hpp index 3149ecdd..cfa62947 100644 --- a/libs/gfx/include/psemek/gfx/texture.hpp +++ b/libs/gfx/include/psemek/gfx/texture.hpp @@ -37,6 +37,8 @@ namespace psemek::gfx void bind() const; void bind(int texture_unit) const; + GLint internal_format() const { return format_; } + geom::vector size() const { return size_; } std::size_t width() const; @@ -82,6 +84,7 @@ namespace psemek::gfx protected: GLuint id_ = 0; + GLint format_ = 0; geom::vector size_ = geom::vector::zero(); explicit basic_texture(std::nullptr_t); @@ -250,9 +253,11 @@ namespace psemek::gfx template basic_texture::basic_texture(basic_texture && other) : id_{other.id_} + , format_{other.format_} , size_{other.size_} { other.id_ = 0; + other.format_ = 0; other.size_ = other.size_.zero(); } @@ -263,6 +268,7 @@ namespace psemek::gfx reset(); std::swap(id_, other.id_); + std::swap(format_, other.format_); std::swap(size_, other.size_); return *this; } @@ -285,6 +291,7 @@ namespace psemek::gfx if (id_ != 0) gl::DeleteTextures(1, &id_); id_ = 0; + format_ = 0; size_ = size_.zero(); } @@ -351,6 +358,7 @@ namespace psemek::gfx gl::TexImage3D(Target, 0, internal_format, size[0], size[1], size[2], 0, format, type, data); } + format_ = internal_format; size_ = size; } @@ -598,4 +606,10 @@ namespace psemek::gfx return result; } + template + std::size_t memory_usage(basic_texture const & texture) + { + return texture.width() * texture.height() * texture.depth() * pixel_size(texture.internal_format()); + } + } diff --git a/libs/gfx/source/pixel.cpp b/libs/gfx/source/pixel.cpp new file mode 100644 index 00000000..24f8c195 --- /dev/null +++ b/libs/gfx/source/pixel.cpp @@ -0,0 +1,76 @@ +#include +#include + +namespace psemek::gfx +{ + + std::size_t pixel_size(GLint internal_format) + { + switch (internal_format) + { + case gl::RGBA32F: return 16; + case gl::RGBA32I: return 16; + case gl::RGBA32UI: return 16; + case gl::RGBA16: return 8; + case gl::RGBA16F: return 8; + case gl::RGBA16I: return 8; + case gl::RGBA16UI: return 8; + case gl::RGBA8: return 4; + case gl::RGBA8UI: return 4; + case gl::SRGB8_ALPHA8: return 4; + case gl::RGB10_A2: return 4; + case gl::RGB10_A2UI: return 4; + case gl::R11F_G11F_B10F: return 4; + case gl::RG32F: return 8; + case gl::RG32I: return 8; + case gl::RG32UI: return 8; + case gl::RG16: return 4; + case gl::RG16F: return 4; + case gl::RGB16I: return 4; + case gl::RGB16UI: return 4; + case gl::RG8: return 2; + case gl::RG8I: return 2; + case gl::RG8UI: return 2; + case gl::R32F: return 4; + case gl::R32I: return 4; + case gl::R32UI: return 4; + case gl::R16F: return 2; + case gl::R16I: return 2; + case gl::R16UI: return 2; + case gl::R8: return 1; + case gl::R8I: return 1; + case gl::R8UI: return 1; + case gl::RGBA16_SNORM: return 8; + case gl::RGBA8_SNORM: return 4; + case gl::RGB32F: return 12; + case gl::RGB32I: return 12; + case gl::RGB32UI: return 12; + case gl::RGB16_SNORM: return 6; + case gl::RGB16F: return 6; + case gl::RGB16: return 6; + case gl::RGB8_SNORM: return 3; + case gl::RGB8: return 3; + case gl::RGB8I: return 3; + case gl::RGB8UI: return 3; + case gl::SRGB8: return 3; + case gl::RGB9_E5: return 4; + case gl::RG16_SNORM: return 4; + case gl::RG8_SNORM: return 2; + case gl::R16_SNORM: return 2; + case gl::R8_SNORM: return 1; + case gl::DEPTH_COMPONENT32F: return 4; + case gl::DEPTH_COMPONENT24: return 3; + case gl::DEPTH_COMPONENT16: return 2; + case gl::DEPTH32F_STENCIL8: return 5; + case gl::DEPTH24_STENCIL8: return 4; + // Assume uncompressed size as an upper bound + case gl::COMPRESSED_RG_RGTC2: return 2; + case gl::COMPRESSED_SIGNED_RG_RGTC2: return 2; + case gl::COMPRESSED_RED_RGTC1: return 1; + case gl::COMPRESSED_SIGNED_RED_RGTC1: return 1; + }; + + throw std::runtime_error(util::to_string("unknown pixel format: 0x", std::hex, internal_format)); + } + +}