@@ -124,8 +124,49 @@ FallbackTexture::FallbackTexture(PixelStorage storage, uint dim, uint3 size, uin
124124 _data = luisa::allocate_with_allocator<std::byte>(static_cast <size_t >(size_pixels) << _pixel_stride_shift);
125125 }
126126}
127+ FallbackTexture::FallbackTexture (PixelStorage storage, uint dim, uint3 size, uint levels, std::byte *external_buffer) noexcept
128+ : _storage{storage}, _mip_levels{levels}, _dimension{dim} {
129+ this ->external = true ;
130+ if (_dimension == 2u ) {
131+ _pixel_stride_shift = std::bit_width (static_cast <uint>(pixel_storage_size (storage, make_uint3 (1u )))) - 1u ;
132+ if (storage == PixelStorage::BC6 || storage == PixelStorage::BC7) {
133+ _pixel_stride_shift = 0u ;
134+ }
135+ _size[0 ] = size.x ;
136+ _size[1 ] = size.y ;
137+ _size[2 ] = 1u ;
138+ _mip_offsets[0 ] = 0u ;
139+ auto sz = make_uint2 (size);
140+ for (auto i = 1u ; i < levels; i++) {
141+ auto s = (sz + block_size - 1u ) / block_size * block_size;
142+ _mip_offsets[i] = _mip_offsets[i - 1u ] + s.x * s.y ;
143+ sz = luisa::max (sz >> 1u , 1u );
144+ }
145+ auto s = (sz + block_size - 1u ) / block_size * block_size;
146+ auto size_pixels = _mip_offsets[levels - 1u ] + s.x * s.y ;
147+ _data = external_buffer;
148+ } else {
149+ _pixel_stride_shift = std::bit_width (static_cast <uint>(pixel_storage_size (storage, make_uint3 (1u )))) - 1u ;
150+ _size[0 ] = size.x ;
151+ _size[1 ] = size.y ;
152+ _size[2 ] = size.z ;
153+ _mip_offsets[0 ] = 0u ;
154+ for (auto i = 1u ; i < levels; i++) {
155+ auto s = (size + block_size - 1u ) / block_size * block_size;
156+ _mip_offsets[i] = _mip_offsets[i - 1u ] + s.x * s.y * s.z ;
157+ size = luisa::max (size >> 1u , 1u );
158+ }
159+ auto s = (size + block_size - 1u ) / block_size * block_size;
160+ auto size_pixels = _mip_offsets[levels - 1u ] + s.x * s.y * s.z ;
161+ _data = external_buffer;
162+ }
163+ }
127164
128- FallbackTexture::~FallbackTexture () noexcept { luisa::deallocate_with_allocator (_data); }
165+ FallbackTexture::~FallbackTexture () noexcept {
166+ if (!external) {
167+ luisa::deallocate_with_allocator (_data);
168+ }
169+ }
129170
130171FallbackTextureView FallbackTexture::view (uint level) const noexcept {
131172 auto size = luisa::max (make_uint3 (_size[0 ], _size[1 ], _size[2 ]) >> level, 1u );
0 commit comments