namespace gli{ namespace detail { inline size_t texel_linear_aAdressing ( extent1d const& Extent, extent1d const& TexelCoord ) { GLI_ASSERT(glm::all(glm::lessThan(TexelCoord, Extent))); return static_cast(TexelCoord.x); } inline size_t texel_linear_adressing ( extent2d const& Extent, extent2d const& TexelCoord ) { GLI_ASSERT(TexelCoord.x < Extent.x); GLI_ASSERT(TexelCoord.y < Extent.y); return static_cast(TexelCoord.x + Extent.x * TexelCoord.y); } inline size_t texel_linear_adressing ( extent3d const& Extent, extent3d const& TexelCoord ) { GLI_ASSERT(TexelCoord.x < Extent.x); GLI_ASSERT(TexelCoord.y < Extent.y); GLI_ASSERT(TexelCoord.z < Extent.z); return static_cast(TexelCoord.x + Extent.x * (TexelCoord.y + Extent.y * TexelCoord.z)); } inline size_t texel_morton_adressing ( extent1d const& Extent, extent1d const& TexelCoord ) { GLI_ASSERT(TexelCoord.x < Extent.x); return TexelCoord.x; } inline size_t texel_morton_adressing ( extent2d const& Extent, extent2d const& TexelCoord ) { GLI_ASSERT(TexelCoord.x < Extent.x && TexelCoord.x >= 0 && TexelCoord.x < std::numeric_limits::max()); GLI_ASSERT(TexelCoord.y < Extent.y && TexelCoord.y >= 0 && TexelCoord.y < std::numeric_limits::max()); glm::u32vec2 const Input(TexelCoord); return static_cast(glm::bitfieldInterleave(Input.x, Input.y)); } inline size_t texel_morton_adressing ( extent3d const& Extent, extent3d const& TexelCoord ) { GLI_ASSERT(TexelCoord.x < Extent.x); GLI_ASSERT(TexelCoord.y < Extent.y); GLI_ASSERT(TexelCoord.z < Extent.z); glm::u32vec3 const Input(TexelCoord); return static_cast(glm::bitfieldInterleave(Input.x, Input.y, Input.z)); } }//namespace detail inline image::image() : Format(static_cast(FORMAT_INVALID)) , BaseLevel(0) , Data(nullptr) , Size(0) {} inline image::image ( format_type Format, extent_type const& Extent ) : Storage(std::make_shared(Format, Extent, 1, 1, 1)) , Format(Format) , BaseLevel(0) , Data(Storage->data()) , Size(compute_size(0)) {} inline image::image ( std::shared_ptr Storage, format_type Format, size_type BaseLayer, size_type BaseFace, size_type BaseLevel ) : Storage(Storage) , Format(Format) , BaseLevel(BaseLevel) , Data(compute_data(BaseLayer, BaseFace, BaseLevel)) , Size(compute_size(BaseLevel)) {} inline image::image ( image const & Image, format_type Format ) : Storage(Image.Storage) , Format(Format) , BaseLevel(Image.BaseLevel) , Data(Image.Data) , Size(Image.Size) { GLI_ASSERT(block_size(Format) == block_size(Image.format())); } inline bool image::empty() const { if(this->Storage.get() == nullptr) return true; return this->Storage->empty(); } inline image::size_type image::size() const { GLI_ASSERT(!this->empty()); return this->Size; } template inline image::size_type image::size() const { GLI_ASSERT(sizeof(genType) <= this->Storage->block_size()); return this->size() / sizeof(genType); } inline image::format_type image::format() const { return this->Format; } inline image::extent_type image::extent() const { GLI_ASSERT(!this->empty()); storage_linear::extent_type const& SrcExtent = this->Storage->extent(this->BaseLevel); storage_linear::extent_type const& DstExtent = SrcExtent * block_extent(this->format()) / this->Storage->block_extent(); return glm::max(DstExtent, storage_linear::extent_type(1)); } inline void* image::data() { GLI_ASSERT(!this->empty()); return this->Data; } inline void const* image::data() const { GLI_ASSERT(!this->empty()); return this->Data; } template inline genType* image::data() { GLI_ASSERT(!this->empty()); GLI_ASSERT(this->Storage->block_size() >= sizeof(genType)); return reinterpret_cast(this->data()); } template inline genType const* image::data() const { GLI_ASSERT(!this->empty()); GLI_ASSERT(this->Storage->block_size() >= sizeof(genType)); return reinterpret_cast(this->data()); } inline void image::clear() { GLI_ASSERT(!this->empty()); memset(this->data(), 0, this->size()); } template inline void image::clear(genType const& Texel) { GLI_ASSERT(!this->empty()); GLI_ASSERT(this->Storage->block_size() == sizeof(genType)); for(size_type TexelIndex = 0; TexelIndex < this->size(); ++TexelIndex) *(this->data() + TexelIndex) = Texel; } inline image::data_type* image::compute_data(size_type BaseLayer, size_type BaseFace, size_type BaseLevel) { size_type const BaseOffset = this->Storage->base_offset(BaseLayer, BaseFace, BaseLevel); return this->Storage->data() + BaseOffset; } inline image::size_type image::compute_size(size_type Level) const { GLI_ASSERT(!this->empty()); return this->Storage->level_size(Level); } template genType image::load(extent_type const& TexelCoord) { GLI_ASSERT(!this->empty()); GLI_ASSERT(!is_compressed(this->format())); GLI_ASSERT(this->Storage->block_size() == sizeof(genType)); GLI_ASSERT(glm::all(glm::lessThan(TexelCoord, this->extent()))); return *(this->data() + detail::texel_linear_adressing(this->extent(), TexelCoord)); } template void image::store(extent_type const& TexelCoord, genType const& Data) { GLI_ASSERT(!this->empty()); GLI_ASSERT(!is_compressed(this->format())); GLI_ASSERT(this->Storage->block_size() == sizeof(genType)); GLI_ASSERT(glm::all(glm::lessThan(TexelCoord, this->extent()))); *(this->data() + detail::texel_linear_adressing(this->extent(), TexelCoord)) = Data; } }//namespace gli