From eddb5cfd959eaa202ee6f95cd2049349ec920829 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 4 Dec 2021 02:25:14 +0200 Subject: [PATCH] Store the number of mipmap levels in the Texture base class --- source/backends/opengl/texture1d_backend.cpp | 10 ++++---- source/backends/opengl/texture2d_backend.cpp | 10 ++++---- .../opengl/texture2darray_backend.cpp | 2 +- source/backends/opengl/texture3d_backend.cpp | 10 ++++---- .../backends/opengl/texturecube_backend.cpp | 10 ++++---- .../backends/vulkan/framebuffer_backend.cpp | 2 +- source/backends/vulkan/texture1d_backend.cpp | 9 +------ source/backends/vulkan/texture1d_backend.h | 1 - source/backends/vulkan/texture2d_backend.cpp | 9 +------ source/backends/vulkan/texture2d_backend.h | 1 - .../vulkan/texture2darray_backend.cpp | 1 - source/backends/vulkan/texture3d_backend.cpp | 9 +------ source/backends/vulkan/texture3d_backend.h | 1 - source/backends/vulkan/texture_backend.cpp | 24 +++++++++++-------- source/backends/vulkan/texture_backend.h | 5 ++-- .../backends/vulkan/texturecube_backend.cpp | 9 +------ source/backends/vulkan/texturecube_backend.h | 1 - source/core/texture.cpp | 7 ++++++ source/core/texture.h | 2 ++ source/core/texture1d.cpp | 15 ++++-------- source/core/texture1d.h | 2 -- source/core/texture2d.cpp | 15 ++++-------- source/core/texture2d.h | 1 - source/core/texture2darray.cpp | 2 +- source/core/texture3d.cpp | 21 ++++++---------- source/core/texture3d.h | 2 -- source/core/texturecube.cpp | 15 ++++-------- source/core/texturecube.h | 2 -- 28 files changed, 71 insertions(+), 127 deletions(-) diff --git a/source/backends/opengl/texture1d_backend.cpp b/source/backends/opengl/texture1d_backend.cpp index 8e33d278..aa9e1f29 100644 --- a/source/backends/opengl/texture1d_backend.cpp +++ b/source/backends/opengl/texture1d_backend.cpp @@ -25,20 +25,20 @@ void OpenGLTexture1D::allocate() if(ARB_texture_storage) { if(ARB_direct_state_access) - glTextureStorage1D(id, self.levels, gl_fmt, self.width); + glTextureStorage1D(id, n_levels, gl_fmt, self.width); else { bind_scratch(); - glTexStorage1D(target, self.levels, gl_fmt, self.width); + glTexStorage1D(target, n_levels, gl_fmt, self.width); } } else { bind_scratch(); - glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, self.levels-1); + glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, n_levels-1); GLenum comp = get_gl_components(get_components(storage_fmt)); GLenum type = get_gl_type(get_component_type(storage_fmt)); - for(unsigned i=0; i>=2) + for(unsigned i=0; i>=2) total_size += level_size; return total_size; } diff --git a/source/backends/opengl/texture2d_backend.cpp b/source/backends/opengl/texture2d_backend.cpp index 54c82280..ed10f6c1 100644 --- a/source/backends/opengl/texture2d_backend.cpp +++ b/source/backends/opengl/texture2d_backend.cpp @@ -50,20 +50,20 @@ void OpenGLTexture2D::allocate() if(ARB_texture_storage) { if(ARB_direct_state_access) - glTextureStorage2D(id, self.levels, gl_fmt, self.width, self.height); + glTextureStorage2D(id, n_levels, gl_fmt, self.width, self.height); else { bind_scratch(); - glTexStorage2D(target, self.levels, gl_fmt, self.width, self.height); + glTexStorage2D(target, n_levels, gl_fmt, self.width, self.height); } } else { bind_scratch(); - glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, self.levels-1); + glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, n_levels-1); GLenum comp = get_gl_components(get_components(storage_fmt)); GLenum type = get_gl_type(get_component_type(storage_fmt)); - for(unsigned i=0; i>=2) + for(unsigned i=0; i>=2) total_size += level_size; return total_size; } diff --git a/source/backends/opengl/texture2darray_backend.cpp b/source/backends/opengl/texture2darray_backend.cpp index edca615d..5e04dc0d 100644 --- a/source/backends/opengl/texture2darray_backend.cpp +++ b/source/backends/opengl/texture2darray_backend.cpp @@ -17,7 +17,7 @@ size_t OpenGLTexture2DArray::get_data_size() const size_t level_size = width*height*get_pixel_size(format); size_t total_size = level_size; - for(unsigned i=0; i>=2) + for(unsigned i=0; i>=2) total_size += level_size*depth; return total_size; } diff --git a/source/backends/opengl/texture3d_backend.cpp b/source/backends/opengl/texture3d_backend.cpp index f446e653..81783850 100644 --- a/source/backends/opengl/texture3d_backend.cpp +++ b/source/backends/opengl/texture3d_backend.cpp @@ -30,11 +30,11 @@ void OpenGLTexture3D::allocate() if(ARB_texture_storage) { if(ARB_direct_state_access) - glTextureStorage3D(id, self.levels, gl_fmt, self.width, self.height, self.depth); + glTextureStorage3D(id, n_levels, gl_fmt, self.width, self.height, self.depth); else { bind_scratch(); - glTexStorage3D(target, self.levels, gl_fmt, self.width, self.height, self.depth); + glTexStorage3D(target, n_levels, gl_fmt, self.width, self.height, self.depth); } } else @@ -42,12 +42,12 @@ void OpenGLTexture3D::allocate() bind_scratch(); GLenum comp = get_gl_components(get_components(storage_fmt)); GLenum type = get_gl_type(get_component_type(storage_fmt)); - for(unsigned i=0; i>=2) + for(unsigned i=0; i>=2) total_size += level_size; return total_size; } diff --git a/source/backends/opengl/texturecube_backend.cpp b/source/backends/opengl/texturecube_backend.cpp index 142e343d..e363f6fb 100644 --- a/source/backends/opengl/texturecube_backend.cpp +++ b/source/backends/opengl/texturecube_backend.cpp @@ -37,11 +37,11 @@ void OpenGLTextureCube::allocate() if(ARB_texture_storage) { if(ARB_direct_state_access) - glTextureStorage2D(id, self.levels, gl_fmt, self.size, self.size); + glTextureStorage2D(id, n_levels, gl_fmt, self.size, self.size); else { bind_scratch(); - glTexStorage2D(target, self.levels, gl_fmt, self.size, self.size); + glTexStorage2D(target, n_levels, gl_fmt, self.size, self.size); } } else @@ -49,13 +49,13 @@ void OpenGLTextureCube::allocate() bind_scratch(); GLenum comp = get_gl_components(get_components(storage_fmt)); GLenum type = get_gl_type(get_component_type(storage_fmt)); - for(unsigned i=0; i(this)->get_level_size(i); for(unsigned j=0; j<6; ++j) glTexImage2D(get_gl_cube_face(j), i, gl_fmt, lv_size, lv_size, 0, comp, type, 0); } - glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, self.levels-1); + glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, n_levels-1); } apply_swizzle(); @@ -83,7 +83,7 @@ size_t OpenGLTextureCube::get_data_size() const size_t level_size = self.size*self.size*get_pixel_size(storage_fmt); size_t total_size = level_size; - for(unsigned i=0; i>=2) + for(unsigned i=0; i>=2) total_size += level_size; return total_size; } diff --git a/source/backends/vulkan/framebuffer_backend.cpp b/source/backends/vulkan/framebuffer_backend.cpp index 2ebd8b33..8ef69ecd 100644 --- a/source/backends/vulkan/framebuffer_backend.cpp +++ b/source/backends/vulkan/framebuffer_backend.cpp @@ -85,7 +85,7 @@ void VulkanFramebuffer::update(unsigned) const void VulkanFramebuffer::prepare_image_layouts(bool discard) const { for(const Framebuffer::Attachment &a: static_cast(this)->attachments) - a.tex->change_layout(0, a.level, get_vulkan_attachment_layout(get_components(a.tex->get_format())), discard); + a.tex->change_layout(a.level, get_vulkan_attachment_layout(get_components(a.tex->get_format())), discard); } void VulkanFramebuffer::set_debug_name(const string &name) diff --git a/source/backends/vulkan/texture1d_backend.cpp b/source/backends/vulkan/texture1d_backend.cpp index e27f371b..d7416484 100644 --- a/source/backends/vulkan/texture1d_backend.cpp +++ b/source/backends/vulkan/texture1d_backend.cpp @@ -19,7 +19,6 @@ void VulkanTexture1D::fill_image_info(void *ii) const VkImageCreateInfo *image_info = static_cast(ii); image_info->imageType = VK_IMAGE_TYPE_1D; image_info->extent.width = self.width; - image_info->mipLevels = self.levels; } void VulkanTexture1D::sub_image(unsigned level, int x, unsigned wd, const void *data) @@ -32,8 +31,7 @@ void VulkanTexture1D::sub_image(unsigned level, int x, unsigned wd, const void * size_t data_size = wd*get_pixel_size(storage_fmt); void *staging = device.get_transfer_queue().prepare_transfer(this, false, data_size, [this, level, discard](){ - unsigned n_levels = static_cast(this)->levels; - change_layout(n_levels, level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard); + change_layout(level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard); }, [this, level, x, wd](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){ const VulkanFunctions &vk = device.get_functions(); @@ -52,11 +50,6 @@ void VulkanTexture1D::sub_image(unsigned level, int x, unsigned wd, const void * stage_pixels(staging, data, wd); } -void VulkanTexture1D::generate_mipmap() -{ - generate_mipmap_levels(static_cast(this)->levels); -} - void VulkanTexture1D::fill_mipmap_blit(unsigned level, void *b) { const Texture1D &self = *static_cast(this); diff --git a/source/backends/vulkan/texture1d_backend.h b/source/backends/vulkan/texture1d_backend.h index 675da1b2..fdc74d9d 100644 --- a/source/backends/vulkan/texture1d_backend.h +++ b/source/backends/vulkan/texture1d_backend.h @@ -13,7 +13,6 @@ protected: virtual void fill_image_info(void *) const; void sub_image(unsigned, int, unsigned, const void *); - virtual void generate_mipmap(); virtual void fill_mipmap_blit(unsigned, void *); public: diff --git a/source/backends/vulkan/texture2d_backend.cpp b/source/backends/vulkan/texture2d_backend.cpp index 3b94e766..3e88898b 100644 --- a/source/backends/vulkan/texture2d_backend.cpp +++ b/source/backends/vulkan/texture2d_backend.cpp @@ -20,7 +20,6 @@ void VulkanTexture2D::fill_image_info(void *ii) const image_info->imageType = VK_IMAGE_TYPE_2D; image_info->extent.width = self.width; image_info->extent.height = self.height; - image_info->mipLevels = self.levels; } void VulkanTexture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, const void *data) @@ -33,8 +32,7 @@ void VulkanTexture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsig size_t data_size = wd*ht*get_pixel_size(storage_fmt); void *staging = device.get_transfer_queue().prepare_transfer(this, false, data_size, [this, level, discard](){ - unsigned n_levels = static_cast(this)->levels; - change_layout(n_levels, level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard); + change_layout(level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard); }, [this, level, x, y, wd, ht](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){ const VulkanFunctions &vk = device.get_functions(); @@ -53,11 +51,6 @@ void VulkanTexture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsig stage_pixels(staging, data, wd*ht); } -void VulkanTexture2D::generate_mipmap() -{ - generate_mipmap_levels(static_cast(this)->levels); -} - void VulkanTexture2D::fill_mipmap_blit(unsigned level, void *b) { const Texture2D &self = *static_cast(this); diff --git a/source/backends/vulkan/texture2d_backend.h b/source/backends/vulkan/texture2d_backend.h index cfd5ff3d..d4b7db1d 100644 --- a/source/backends/vulkan/texture2d_backend.h +++ b/source/backends/vulkan/texture2d_backend.h @@ -13,7 +13,6 @@ protected: virtual void fill_image_info(void *) const; void sub_image(unsigned, int, int, unsigned, unsigned, const void *); - virtual void generate_mipmap(); virtual void fill_mipmap_blit(unsigned, void *); public: diff --git a/source/backends/vulkan/texture2darray_backend.cpp b/source/backends/vulkan/texture2darray_backend.cpp index cff3a816..63e969e8 100644 --- a/source/backends/vulkan/texture2darray_backend.cpp +++ b/source/backends/vulkan/texture2darray_backend.cpp @@ -14,7 +14,6 @@ void VulkanTexture2DArray::fill_image_info(void *ii) const image_info->imageType = VK_IMAGE_TYPE_2D; image_info->extent.width = width; image_info->extent.height = height; - image_info->mipLevels = levels; image_info->arrayLayers = depth; } diff --git a/source/backends/vulkan/texture3d_backend.cpp b/source/backends/vulkan/texture3d_backend.cpp index ee3490a7..05ed5182 100644 --- a/source/backends/vulkan/texture3d_backend.cpp +++ b/source/backends/vulkan/texture3d_backend.cpp @@ -25,7 +25,6 @@ void VulkanTexture3D::fill_image_info(void *ii) const image_info->extent.width = self.width; image_info->extent.height = self.height; image_info->extent.depth = self.depth; - image_info->mipLevels = self.levels; } void VulkanTexture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsigned ht, unsigned dp, const void *data) @@ -38,8 +37,7 @@ void VulkanTexture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd size_t data_size = wd*ht*dp*get_pixel_size(storage_fmt); void *staging = device.get_transfer_queue().prepare_transfer(this, false, data_size, [this, level, discard](){ - unsigned n_levels = static_cast(this)->levels; - change_layout(n_levels, level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard); + change_layout(level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard); }, [this, level, x, y, z, wd, ht, dp](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){ const VulkanFunctions &vk = device.get_functions(); @@ -58,11 +56,6 @@ void VulkanTexture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd stage_pixels(staging, data, wd*ht*dp); } -void VulkanTexture3D::generate_mipmap() -{ - generate_mipmap_levels(static_cast(this)->levels); -} - void VulkanTexture3D::fill_mipmap_blit(unsigned level, void *b) { const Texture3D &self = *static_cast(this); diff --git a/source/backends/vulkan/texture3d_backend.h b/source/backends/vulkan/texture3d_backend.h index e1c8f8f5..49b7497c 100644 --- a/source/backends/vulkan/texture3d_backend.h +++ b/source/backends/vulkan/texture3d_backend.h @@ -14,7 +14,6 @@ protected: virtual void fill_image_info(void *) const; void sub_image(unsigned, int, int, int, unsigned, unsigned, unsigned, const void *); - virtual void generate_mipmap(); virtual void fill_mipmap_blit(unsigned, void *); bool is_array() const; diff --git a/source/backends/vulkan/texture_backend.cpp b/source/backends/vulkan/texture_backend.cpp index dd19c636..ec6d5047 100644 --- a/source/backends/vulkan/texture_backend.cpp +++ b/source/backends/vulkan/texture_backend.cpp @@ -49,7 +49,7 @@ void VulkanTexture::allocate() image_info.extent.width = 1; image_info.extent.height = 1; image_info.extent.depth = 1; - image_info.mipLevels = 1; + image_info.mipLevels = self.n_levels; image_info.arrayLayers = 1; image_info.samples = VK_SAMPLE_COUNT_1_BIT; image_info.tiling = VK_IMAGE_TILING_OPTIMAL; @@ -73,7 +73,7 @@ void VulkanTexture::allocate() memory_id = device.get_allocator().allocate(handle, DEVICE_MEMORY); // Trigger a layout transition if the image is used before uploading data. - change_layout(0, -1, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true); + change_layout(-1, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true); } VkImageViewCreateInfo view_info = { }; @@ -137,15 +137,17 @@ void VulkanTexture::stage_pixels(void *staging, const void *data, size_t count) } } -void VulkanTexture::generate_mipmap_levels(unsigned n_levels) +void VulkanTexture::generate_mipmap() { + unsigned n_levels = static_cast(this)->n_levels; + TransferQueue &tq = device.get_transfer_queue(); for(unsigned i=0; i+1(this)->storage_fmt)); - if(n_levels>0) - device.get_synchronizer().split_image_mipmap(handle, aspect, n_levels); + const Texture &self = *static_cast(this); + + unsigned aspect = get_vulkan_aspect(get_components(self.storage_fmt)); + if(level>=0) + device.get_synchronizer().split_image_mipmap(handle, aspect, self.n_levels); device.get_synchronizer().change_image_layout(handle, aspect, level, layout, discard); } diff --git a/source/backends/vulkan/texture_backend.h b/source/backends/vulkan/texture_backend.h index dad8834b..0907fea0 100644 --- a/source/backends/vulkan/texture_backend.h +++ b/source/backends/vulkan/texture_backend.h @@ -32,11 +32,10 @@ protected: void stage_pixels(void *, const void *, size_t); - virtual void generate_mipmap() = 0; - void generate_mipmap_levels(unsigned); + void generate_mipmap(); virtual void fill_mipmap_blit(unsigned, void *) = 0; - void change_layout(unsigned, int, unsigned, bool) const; + void change_layout(int, unsigned, bool) const; void set_debug_name(const std::string &); void set_vulkan_object_names() const; diff --git a/source/backends/vulkan/texturecube_backend.cpp b/source/backends/vulkan/texturecube_backend.cpp index 6a4e598c..4e0cfe61 100644 --- a/source/backends/vulkan/texturecube_backend.cpp +++ b/source/backends/vulkan/texturecube_backend.cpp @@ -21,7 +21,6 @@ void VulkanTextureCube::fill_image_info(void *ii) const image_info->imageType = VK_IMAGE_TYPE_2D; image_info->extent.width = self.size; image_info->extent.height = self.size; - image_info->mipLevels = self.levels; image_info->arrayLayers = 6; } @@ -35,8 +34,7 @@ void VulkanTextureCube::sub_image(unsigned face, unsigned level, int x, int y, u size_t data_size = wd*ht*get_pixel_size(storage_fmt); void *staging = device.get_transfer_queue().prepare_transfer(this, false, data_size, [this, level, discard](){ - unsigned n_levels = static_cast(this)->levels; - change_layout(n_levels, level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard); + change_layout(level, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, discard); }, [this, face, level, x, y, wd, ht](VkCommandBuffer cmd_buf, VkBuffer staging_buf, size_t src_off){ const VulkanFunctions &vk = device.get_functions(); @@ -55,11 +53,6 @@ void VulkanTextureCube::sub_image(unsigned face, unsigned level, int x, int y, u stage_pixels(staging, data, wd*ht); } -void VulkanTextureCube::generate_mipmap() -{ - generate_mipmap_levels(static_cast(this)->levels); -} - void VulkanTextureCube::fill_mipmap_blit(unsigned level, void *b) { const TextureCube &self = *static_cast(this); diff --git a/source/backends/vulkan/texturecube_backend.h b/source/backends/vulkan/texturecube_backend.h index d7730897..1146c705 100644 --- a/source/backends/vulkan/texturecube_backend.h +++ b/source/backends/vulkan/texturecube_backend.h @@ -13,7 +13,6 @@ protected: virtual void fill_image_info(void *) const; void sub_image(unsigned, unsigned, int, int, unsigned, unsigned, const void *); - virtual void generate_mipmap(); virtual void fill_mipmap_blit(unsigned, void *); public: diff --git a/source/core/texture.cpp b/source/core/texture.cpp index 73dd39b6..0d7a8151 100644 --- a/source/core/texture.cpp +++ b/source/core/texture.cpp @@ -34,6 +34,13 @@ void Texture::set_format(PixelFormat fmt) swizzle = swiz; } +unsigned Texture::count_levels(unsigned size) +{ + unsigned n = 0; + for(; size; size>>=1, ++n) ; + return n; +} + void Texture::load_image(const string &fn, unsigned lv) { Graphics::Image img; diff --git a/source/core/texture.h b/source/core/texture.h index 24d74964..eb5275c6 100644 --- a/source/core/texture.h +++ b/source/core/texture.h @@ -73,12 +73,14 @@ protected: PixelFormat format = NO_PIXELFORMAT; PixelFormat storage_fmt = NO_PIXELFORMAT; ComponentSwizzle swizzle = NO_SWIZZLE; + unsigned n_levels = 0; bool use_srgb_format = false; bool auto_gen_mipmap = false; Texture(unsigned); void set_format(PixelFormat); + static unsigned count_levels(unsigned); public: PixelFormat get_format() const { return format; } diff --git a/source/core/texture1d.cpp b/source/core/texture1d.cpp index d6aa1a34..ce5d3727 100644 --- a/source/core/texture1d.cpp +++ b/source/core/texture1d.cpp @@ -10,7 +10,7 @@ void Texture1D::storage(PixelFormat fmt, unsigned wd, unsigned lv) { if(width>0) { - if(fmt!=format || wd!=width || (lv && lv!=levels)) + if(fmt!=format || wd!=width || (lv && lv!=n_levels)) throw incompatible_data("Texture1D::storage"); return; } @@ -19,9 +19,9 @@ void Texture1D::storage(PixelFormat fmt, unsigned wd, unsigned lv) set_format(fmt); width = wd; - levels = get_n_levels(); + n_levels = count_levels(width); if(lv) - levels = min(levels, lv); + n_levels = min(n_levels, lv); allocate(); } @@ -35,7 +35,7 @@ void Texture1D::sub_image(unsigned level, unsigned x, unsigned wd, const void *d { if(width==0) throw invalid_operation("Texture1D::sub_image"); - if(level>=levels || x>width || x+wd>width) + if(level>=n_levels || x>width || x+wd>width) throw out_of_range("Texture1D::sub_image"); Texture1DBackend::sub_image(level, x, wd, data); @@ -50,13 +50,6 @@ void Texture1D::image(const Graphics::Image &img, unsigned lv) image(0, img.get_pixels()); } -unsigned Texture1D::get_n_levels() const -{ - unsigned n = 0; - for(unsigned s=width; s; s>>=1, ++n) ; - return n; -} - unsigned Texture1D::get_level_size(unsigned level) const { return width>>level; diff --git a/source/core/texture1d.h b/source/core/texture1d.h index 16c88a18..abe6c887 100644 --- a/source/core/texture1d.h +++ b/source/core/texture1d.h @@ -29,7 +29,6 @@ public: private: unsigned width = 0; - unsigned levels = 0; public: /** Sets storage format and size and allocates memory for the texture. If @@ -49,7 +48,6 @@ public: unsigned get_width() const { return width; } private: - unsigned get_n_levels() const; unsigned get_level_size(unsigned) const; }; diff --git a/source/core/texture2d.cpp b/source/core/texture2d.cpp index c9aab79a..7ac1c5ec 100644 --- a/source/core/texture2d.cpp +++ b/source/core/texture2d.cpp @@ -15,7 +15,7 @@ void Texture2D::storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned lv) { if(width>0) { - if(fmt!=format || wd!=width || ht!=height || (lv && lv!=levels)) + if(fmt!=format || wd!=width || ht!=height || (lv && lv!=n_levels)) throw incompatible_data("Texture2D::storage"); return; } @@ -25,9 +25,9 @@ void Texture2D::storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned lv) set_format(fmt); width = wd; height = ht; - levels = get_n_levels(); + n_levels = count_levels(max(width, height)); if(lv>0) - levels = min(levels, lv); + n_levels = min(n_levels, lv); allocate(); } @@ -42,7 +42,7 @@ void Texture2D::sub_image(unsigned level, unsigned x, unsigned y, unsigned wd, u { if(width==0 || height==0) throw invalid_operation("Texture2D::sub_image"); - if(level>=levels || x>width || x+wd>width || y>height || y+ht>height) + if(level>=n_levels || x>width || x+wd>width || y>height || y+ht>height) throw out_of_range("Texture2D::sub_image"); Texture2DBackend::sub_image(level, x, y, wd, ht, data); @@ -54,13 +54,6 @@ void Texture2D::image(const Graphics::Image &img, unsigned lv) image(0, img.get_pixels()); } -unsigned Texture2D::get_n_levels() const -{ - unsigned n = 0; - for(unsigned s=max(width, height); s; s>>=1, ++n) ; - return n; -} - LinAl::Vector Texture2D::get_level_size(unsigned level) const { unsigned w = width>>level; diff --git a/source/core/texture2d.h b/source/core/texture2d.h index fbcee696..05c3283b 100644 --- a/source/core/texture2d.h +++ b/source/core/texture2d.h @@ -31,7 +31,6 @@ public: private: unsigned width = 0; unsigned height = 0; - unsigned levels = 0; public: Texture2D() = default; diff --git a/source/core/texture2darray.cpp b/source/core/texture2darray.cpp index 52f5fd71..07f04c69 100644 --- a/source/core/texture2darray.cpp +++ b/source/core/texture2darray.cpp @@ -8,7 +8,7 @@ namespace GL { void Texture2DArray::layer_image(unsigned level, unsigned z, const void *data) { - if(level>=levels || z>=depth) + if(level>=n_levels || z>=depth) throw out_of_range("Texture2DArray::layer_image"); LinAl::Vector size = get_level_size(level); diff --git a/source/core/texture3d.cpp b/source/core/texture3d.cpp index 496b5f1f..0ee2e800 100644 --- a/source/core/texture3d.cpp +++ b/source/core/texture3d.cpp @@ -15,7 +15,7 @@ void Texture3D::storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned dp, { if(width>0) { - if(fmt!=format || wd!=width || ht!=height || dp!=depth || (lv && lv!=levels)) + if(fmt!=format || wd!=width || ht!=height || dp!=depth || (lv && lv!=n_levels)) throw incompatible_data("Texture3D::storage"); return; } @@ -26,9 +26,12 @@ void Texture3D::storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned dp, width = wd; height = ht; depth = dp; - levels = get_n_levels(); + unsigned size = max(width, height); + if(!is_array()) + size = max(size, depth); + n_levels = count_levels(size); if(lv>0) - levels = min(levels, lv); + n_levels = min(n_levels, lv); allocate(); } @@ -43,7 +46,7 @@ void Texture3D::sub_image(unsigned level, unsigned x, unsigned y, unsigned z, un { if(width==0 || height==0 || depth==0) throw invalid_operation("Texture3D::sub_image"); - if(level>=levels || x>width || x+wd>width || y>height || y+ht>height || z>depth || z+dp>depth) + if(level>=n_levels || x>width || x+wd>width || y>height || y+ht>height || z>depth || z+dp>depth) throw out_of_range("Texture3D::sub_image"); Texture3DBackend::sub_image(level, x, y, z, wd, ht, dp, data); @@ -63,16 +66,6 @@ void Texture3D::image(const Graphics::Image &img, unsigned lv) image(0, img.get_pixels()); } -unsigned Texture3D::get_n_levels() const -{ - unsigned s = max(width, height); - if(!is_array()) - s = max(s, depth); - unsigned n = 0; - for(; s; s>>=1, ++n) ; - return n; -} - LinAl::Vector Texture3D::get_level_size(unsigned level) const { unsigned w = width>>level; diff --git a/source/core/texture3d.h b/source/core/texture3d.h index 3009e148..e7e3a79e 100644 --- a/source/core/texture3d.h +++ b/source/core/texture3d.h @@ -32,7 +32,6 @@ protected: unsigned width = 0; unsigned height = 0; unsigned depth = 0; - unsigned levels = 0; Texture3D(unsigned); public: @@ -63,7 +62,6 @@ public: unsigned get_height() const { return height; } unsigned get_depth() const { return depth; } protected: - unsigned get_n_levels() const; LinAl::Vector get_level_size(unsigned) const; }; diff --git a/source/core/texturecube.cpp b/source/core/texturecube.cpp index 2f36f336..bfa63873 100644 --- a/source/core/texturecube.cpp +++ b/source/core/texturecube.cpp @@ -33,7 +33,7 @@ void TextureCube::storage(PixelFormat fmt, unsigned sz, unsigned lv) { if(size>0) { - if(fmt!=format || sz!=size || (lv && lv!=levels)) + if(fmt!=format || sz!=size || (lv && lv!=n_levels)) throw incompatible_data("TextureCube::storage"); return; } @@ -42,9 +42,9 @@ void TextureCube::storage(PixelFormat fmt, unsigned sz, unsigned lv) set_format(fmt); size = sz; - levels = get_n_levels(); + n_levels = count_levels(size); if(lv>0) - levels = min(levels, lv); + n_levels = min(n_levels, lv); allocate(); } @@ -67,7 +67,7 @@ void TextureCube::sub_image(TextureCubeFace face, unsigned level, unsigned x, un { if(size==0) throw invalid_operation("TextureCube::sub_image"); - if(level>=levels || x>size || x+wd>size || y>size || y+ht>size) + if(level>=n_levels || x>size || x+wd>size || y>size || y+ht>size) throw out_of_range("TextureCube::sub_image"); TextureCubeBackend::sub_image(face, level, x, y, wd, ht, data); @@ -101,13 +101,6 @@ void TextureCube::image(const Graphics::Image &img, unsigned lv) image(0, img.get_pixels()); } -unsigned TextureCube::get_n_levels() const -{ - unsigned n = 0; - for(unsigned s=size; s; s>>=1, ++n) ; - return n; -} - unsigned TextureCube::get_level_size(unsigned level) const { return size>>level; diff --git a/source/core/texturecube.h b/source/core/texturecube.h index d444fee5..127251d6 100644 --- a/source/core/texturecube.h +++ b/source/core/texturecube.h @@ -49,7 +49,6 @@ public: private: unsigned size = 0; - unsigned levels = 0; static const Vector3 directions[6]; static const unsigned orientations[12]; @@ -82,7 +81,6 @@ public: unsigned get_size() const { return size; } private: - unsigned get_n_levels() const; unsigned get_level_size(unsigned) const; public: -- 2.43.0