11 #ifndef hifi_gpu_Texture_h
12 #define hifi_gpu_Texture_h
21 #include <shared/Storage.h>
22 #include <shared/FileCache.h>
23 #include <RegisteredMetaTypes.h>
30 const int ABSOLUTE_MAX_TEXTURE_NUM_PIXELS = 8192 * 8192;
34 using KTXUniquePointer = std::unique_ptr<KTX>;
36 using KTXDescriptorPointer = std::unique_ptr<KTXDescriptor>;
39 using KeyValues = std::list<KeyValue>;
42 namespace khronos {
namespace gl {
namespace texture {
43 enum class InternalFormat: uint32_t;
48 enum class BackendTarget {
54 const std::string SOURCE_HASH_KEY {
"hifi.sourceHash" };
56 const uint8 SOURCE_HASH_BYTES = 16;
61 class SphericalHarmonics {
63 glm::vec3 L00 ;
float spare0;
64 glm::vec3 L1m1 ;
float spare1;
65 glm::vec3 L10 ;
float spare2;
66 glm::vec3 L11 ;
float spare3;
67 glm::vec3 L2m2 ;
float spare4;
68 glm::vec3 L2m1 ;
float spare5;
69 glm::vec3 L20 ;
float spare6;
70 glm::vec3 L21 ;
float spare7;
71 glm::vec3 L22 ;
float spare8;
73 static const int NUM_COEFFICIENTS = 9;
90 void assignPreset(
int p);
92 void evalFromTexture(
const Texture& texture, gpu::BackendTarget target);
94 typedef std::shared_ptr< SphericalHarmonics > SHPointer;
100 ser << h.L00 << h.spare0;
101 ser << h.L1m1 << h.spare1;
102 ser << h.L10 << h.spare2;
103 ser << h.L11 << h.spare3;
104 ser << h.L2m2 << h.spare4;
105 ser << h.L2m1 << h.spare5;
106 ser << h.L20 << h.spare6;
107 ser << h.L21 << h.spare7;
108 ser << h.L22 << h.spare8;
115 des >> h.L00 >> h.spare0;
116 des >> h.L1m1 >> h.spare1;
117 des >> h.L10 >> h.spare2;
118 des >> h.L11 >> h.spare3;
119 des >> h.L2m2 >> h.spare4;
120 des >> h.L2m1 >> h.spare5;
121 des >> h.L20 >> h.spare6;
122 des >> h.L21 >> h.spare7;
123 des >> h.L22 >> h.spare8;
127 enum class TextureUsageType : uint8 {
135 static ContextMetricCount _textureCPUCount;
136 static ContextMetricSize _textureCPUMemSize;
138 static std::atomic<Size> _allowedCPUMemoryUsage;
139 static std::atomic<bool> _enableSparseTextures;
140 static void updateTextureCPUMemoryUsage(Size prevObjectSize, Size newObjectSize);
143 static const uint32_t CUBE_FACE_COUNT { 6 };
144 static uint32_t getTextureCPUCount();
145 static Size getTextureCPUMemSize();
147 static Size getAllowedGPUMemoryUsage();
148 static void setAllowedGPUMemoryUsage(Size size);
150 static bool getEnableSparseTextures();
151 static void setEnableSparseTextures(
bool enabled);
153 using ExternalRecycler = std::function<void(uint32,
void*)>;
154 using ExternalIdAndFence = std::pair<uint32, void*>;
155 using ExternalUpdates = std::list<ExternalIdAndFence>;
167 typedef std::bitset<NUM_FLAGS> Flags;
172 Usage() : _flags(0) {}
173 Usage(
const Flags& flags) : _flags(flags) {}
175 bool operator== (
const Usage& rhs)
const {
return _flags == rhs._flags; }
176 bool operator!= (
const Usage& rhs)
const {
return _flags != rhs._flags; }
184 Usage build()
const {
return Usage(_flags); }
186 Builder& withColor() { _flags.set(COLOR);
return (*
this); }
187 Builder& withNormal() { _flags.set(NORMAL);
return (*
this); }
188 Builder& withAlpha() { _flags.set(ALPHA);
return (*
this); }
189 Builder& withAlphaMask() { _flags.set(ALPHA_MASK);
return (*
this); }
191 Usage(
const Builder& builder) : Usage(builder._flags) {}
193 bool isColor()
const {
return _flags[COLOR]; }
194 bool isNormal()
const {
return _flags[NORMAL]; }
196 bool isAlpha()
const {
return _flags[ALPHA]; }
197 bool isAlphaMask()
const {
return _flags[ALPHA_MASK]; }
199 bool operator==(
const Usage& usage) {
return (_flags == usage._flags); }
200 bool operator!=(
const Usage& usage) {
return (_flags != usage._flags); }
214 CUBE_FACE_RIGHT_POS_X = 0,
215 CUBE_FACE_LEFT_NEG_X,
217 CUBE_FACE_BOTTOM_NEG_Y,
218 CUBE_FACE_BACK_POS_Z,
219 CUBE_FACE_FRONT_NEG_Z,
225 static const uint32 PACKING_SIZE = 4;
226 static uint8 evalPaddingNumBytes(Size byteSize) {
return (uint8) (3 - (byteSize + 3) % PACKING_SIZE); }
227 static Size evalPaddedSize(Size byteSize) {
return byteSize + (Size) evalPaddingNumBytes(byteSize); }
230 using PixelsPointer = storage::StoragePointer;
234 virtual ~Storage() {}
236 virtual void reset() = 0;
237 virtual PixelsPointer getMipFace(uint16 level, uint8 face = 0)
const = 0;
238 virtual Size getMipFaceSize(uint16 level, uint8 face = 0)
const = 0;
239 virtual void assignMipData(uint16 level,
const storage::StoragePointer& storage) = 0;
240 virtual void assignMipFaceData(uint16 level, uint8 face,
const storage::StoragePointer& storage) = 0;
241 virtual bool isMipAvailable(uint16 level, uint8 face = 0)
const = 0;
242 virtual uint16 minAvailableMipLevel()
const {
return 0; }
243 Texture::Type getType()
const {
return _type; }
245 Stamp getStamp()
const {
return _stamp; }
246 Stamp bumpStamp() {
return ++_stamp; }
248 void setFormat(
const Element& format) { _format = format; }
249 Element getFormat()
const {
return _format; }
254 Texture::Type _type { Texture::TEX_2D };
256 virtual void assignTexture(
Texture* tex);
257 const Texture* getTexture()
const {
return _texture; }
261 class MemoryStorage :
public Storage {
263 void reset()
override;
264 PixelsPointer getMipFace(uint16 level, uint8 face = 0)
const override;
265 Size getMipFaceSize(uint16 level, uint8 face = 0)
const override;
266 void assignMipData(uint16 level,
const storage::StoragePointer& storage)
override;
267 void assignMipFaceData(uint16 level, uint8 face,
const storage::StoragePointer& storage)
override;
268 bool isMipAvailable(uint16 level, uint8 face = 0)
const override;
271 void allocateMip(uint16 level);
272 std::vector<std::vector<PixelsPointer>> _mips;
275 class KtxStorage :
public Storage {
277 KtxStorage(
const storage::StoragePointer& storage);
278 KtxStorage(
const std::string& filename);
279 KtxStorage(
const cache::FilePointer& file);
280 PixelsPointer getMipFace(uint16 level, uint8 face = 0)
const override;
281 Size getMipFaceSize(uint16 level, uint8 face = 0)
const override;
282 bool isMipAvailable(uint16 level, uint8 face = 0)
const override;
283 void assignMipData(uint16 level,
const storage::StoragePointer& storage)
override;
284 void assignMipFaceData(uint16 level, uint8 face,
const storage::StoragePointer& storage)
override;
285 uint16 minAvailableMipLevel()
const override;
287 void reset()
override { }
290 static void releaseOpenKtxFiles();
293 std::shared_ptr<storage::FileStorage> maybeOpenFile()
const;
295 mutable std::shared_ptr<std::mutex> _cacheFileMutex { std::make_shared<std::mutex>() };
296 mutable std::weak_ptr<storage::FileStorage> _cacheFile;
298 static std::vector<std::pair<std::shared_ptr<storage::FileStorage>, std::shared_ptr<std::mutex>>> _cachedKtxFiles;
299 static std::mutex _cachedKtxFilesMutex;
301 storage::StoragePointer _storage;
302 std::string _filename;
303 cache::FilePointer _cacheEntry;
304 std::atomic<uint8_t> _minMipLevelAvailable;
305 size_t _offsetToMinMipKV;
307 ktx::KTXDescriptorPointer _ktxDescriptor;
309 friend class Serializer;
310 friend class Deserializer;
313 uint16 minAvailableMipLevel()
const {
return _storage->minAvailableMipLevel(); };
315 static const uint16 MAX_NUM_MIPS = 0;
316 static const uint16 SINGLE_MIP = 1;
317 static TexturePointer create1D(
const Element& texelFormat, uint16 width, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
318 static TexturePointer create2D(
const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
319 static TexturePointer create2DArray(
const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
320 static TexturePointer create3D(
const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
321 static TexturePointer createCube(
const Element& texelFormat, uint16 width, uint16 numMips = 1,
const Sampler& sampler = Sampler());
322 static TexturePointer createRenderBuffer(
const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
323 static TexturePointer createRenderBufferMultisample(
const Element& texelFormat, uint16 width, uint16 height, uint16 numSamples,
const Sampler& sampler = Sampler());
324 static TexturePointer createRenderBufferArray(
const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
325 static TexturePointer createRenderBufferMultisampleArray(
const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numSamples,
const Sampler& sampler = Sampler());
326 static TexturePointer createStrict(
const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
327 static TexturePointer createExternal(
const ExternalRecycler& recycler,
const Sampler& sampler = Sampler());
330 bool isDefined()
const {
return _defined; }
332 Texture(TextureUsageType usageType);
335 Stamp getStamp()
const {
return _stamp; }
336 Stamp getDataStamp()
const {
return _storage->getStamp(); }
340 Size getSize()
const override {
return _size; }
343 Type getType()
const {
return _type; }
344 TextureUsageType getUsageType()
const {
return _usageType; }
346 bool isDepthStencilRenderTarget()
const;
348 Element getTexelFormat()
const {
return _texelFormat; }
350 void setSize(
int width,
int height);
351 Vec3u getDimensions()
const {
return Vec3u(_width, _height, _depth); }
352 uint16 getWidth()
const {
return _width; }
353 uint16 getHeight()
const {
return _height; }
354 uint16 getDepth()
const {
return _depth; }
356 void setOriginalSize(
int width,
int height);
357 int getOriginalWidth()
const {
return _originalWidth; }
358 int getOriginalHeight()
const {
return _originalHeight; }
363 static uint8 NUM_FACES_PER_TYPE[NUM_TYPES];
364 uint8 getNumFaces()
const {
return NUM_FACES_PER_TYPE[getType()]; }
369 bool isArray()
const {
return _numSlices > 0; }
370 uint16 getNumSlices()
const {
return (isArray() ? _numSlices : 1); }
372 uint16 getNumSamples()
const {
return _numSamples; }
374 static uint16 evalNumSamplesUsed(uint16 numSamplesTried);
375 bool isMultisample()
const {
return _numSamples > 1; }
379 uint16 getMaxMip()
const {
return _maxMipLevel; }
380 uint16 getNumMips()
const {
return _maxMipLevel + 1; }
386 static uint16 evalDimMaxNumMips(uint16 size);
390 uint16 evalMaxNumMips()
const;
391 static uint16 evalMaxNumMips(
const Vec3u& dimensions);
396 static uint16 safeNumMips(uint16 askedNumMips, uint16 maxMips);
399 uint16 safeNumMips(uint16 askedNumMips)
const;
405 Vec3u evalMipDimensions(uint16 level)
const;
406 uint16 evalMipWidth(uint16 level)
const {
return std::max(_width >> level, 1); }
407 uint16 evalMipHeight(uint16 level)
const {
return std::max(_height >> level, 1); }
408 uint16 evalMipDepth(uint16 level)
const {
return std::max(_depth >> level, 1); }
414 static uint16 evalTiledPadding(uint16 length,
int tile) {
int tileMinusOne = (tile - 1);
return (tileMinusOne - (length + tileMinusOne) % tile); }
415 static uint16 evalTiledLength(uint16 length,
int tile) {
return length / tile + (evalTiledPadding(length, tile) != 0); }
416 static uint16 evalTiledWidth(uint16 width,
int tileX) {
return evalTiledLength(width, tileX); }
417 static uint16 evalTiledHeight(uint16 height,
int tileY) {
return evalTiledLength(height, tileY); }
418 static Size evalLineSize(uint16 width,
const Element& format) {
return evalPaddedSize(evalTiledWidth(width, format.getTile().x) * format.getSize()); }
419 static Size evalSurfaceSize(uint16 width, uint16 height,
const Element& format) {
return evalLineSize(width, format) * evalTiledHeight(height, format.getTile().x); }
422 Size evalStoredMipLineSize(uint16 level,
const Element& format)
const {
return evalLineSize(evalMipWidth(level), format); }
423 Size evalStoredMipSurfaceSize(uint16 level,
const Element& format)
const {
return evalSurfaceSize(evalMipWidth(level), evalMipHeight(level), format); }
424 Size evalStoredMipFaceSize(uint16 level,
const Element& format)
const {
return evalStoredMipSurfaceSize(level, format) * evalMipDepth(level); }
425 Size evalStoredMipSize(uint16 level,
const Element& format)
const {
return evalStoredMipFaceSize(level, format) * getNumFaces(); }
428 Size evalMipLineSize(uint16 level)
const {
return evalStoredMipLineSize(level, getTexelFormat()); }
429 Size evalMipSurfaceSize(uint16 level)
const {
return evalStoredMipSurfaceSize(level, getTexelFormat()); }
430 Size evalMipFaceSize(uint16 level)
const {
return evalStoredMipFaceSize(level, getTexelFormat()); }
431 Size evalMipSize(uint16 level)
const {
return evalStoredMipSize(level, getTexelFormat()); }
434 Size evalTotalSize(uint16 startingMip = 0)
const;
437 uint32 evalMipFaceNumTexels(uint16 level)
const {
return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); }
438 uint32 evalMipNumTexels(uint16 level)
const {
return evalMipFaceNumTexels(level) * getNumFaces(); }
441 const std::string& source()
const {
return _source; }
442 void setSource(
const std::string& source) { _source = source; }
443 const std::string& sourceHash()
const {
return _sourceHash; }
444 void setSourceHash(
const std::string& sourceHash) { _sourceHash = sourceHash; }
447 bool setMinMip(uint16 newMinMip);
448 bool incremementMinMip(uint16 count = 1);
449 uint16 getMinMip()
const {
return _minMip; }
450 uint16 usedMipLevels()
const {
return (getNumMips() - _minMip); }
455 void setAutoGenerateMips(
bool enable);
456 bool isAutogenerateMips()
const {
return _autoGenerateMips; }
461 void setStoredMipFormat(
const Element& format);
462 Element getStoredMipFormat()
const;
469 void assignStoredMip(uint16 level, Size size,
const Byte* bytes);
470 void assignStoredMipFace(uint16 level, uint8 face, Size size,
const Byte* bytes);
472 void assignStoredMip(uint16 level, storage::StoragePointer& storage);
473 void assignStoredMipFace(uint16 level, uint8 face, storage::StoragePointer& storage);
476 const PixelsPointer accessStoredMipFace(uint16 level, uint8 face = 0)
const {
return _storage->getMipFace(level, face); }
477 bool isStoredMipFaceAvailable(uint16 level, uint8 face = 0)
const;
478 Size getStoredMipFaceSize(uint16 level, uint8 face = 0)
const {
return _storage->getMipFaceSize(level, face); }
479 Size getStoredMipSize(uint16 level)
const;
480 Size getStoredSize()
const;
482 void setStorage(std::unique_ptr<Storage>& newStorage);
483 void setKtxBacking(
const storage::StoragePointer& storage);
484 void setKtxBacking(
const std::string& filename);
485 void setKtxBacking(
const cache::FilePointer& cacheEntry);
488 void setUsage(
const Usage& usage) { _usage = usage; }
489 Usage getUsage()
const {
return _usage; }
492 bool generateIrradiance(gpu::BackendTarget target);
493 const SHPointer& getIrradiance(uint16 slice = 0)
const {
return _irradiance; }
494 void overrideIrradiance(SHPointer irradiance) { _irradiance = irradiance; }
495 bool isIrradianceValid()
const {
return _isIrradianceValid; }
498 void setSampler(
const Sampler& sampler);
499 const Sampler& getSampler()
const {
return _sampler; }
500 Stamp getSamplerStamp()
const {
return _samplerStamp; }
502 void setFallbackTexture(
const TexturePointer& fallback) { _fallback = fallback; }
503 TexturePointer getFallbackTexture()
const {
return _fallback.lock(); }
505 void setExternalTexture(uint32 externalId,
void* externalFence);
506 void setExternalRecycler(
const ExternalRecycler& recycler);
507 ExternalRecycler getExternalRecycler()
const;
509 bool getImportant()
const {
return _important; }
510 void setImportant(
bool important) { _important = important; }
512 const GPUObjectPointer gpuObject {};
514 ExternalUpdates getUpdates()
const;
517 static ktx::KTXUniquePointer serialize(
const Texture& texture,
const glm::ivec2& originalSize);
519 static std::pair<TexturePointer, glm::ivec2> build(
const ktx::KTXDescriptor& descriptor);
520 static std::pair<TexturePointer, glm::ivec2> unserialize(
const std::string& ktxFile);
521 static std::pair<TexturePointer, glm::ivec2> unserialize(
const cache::FilePointer& cacheEntry,
const std::string& source = std::string());
523 static bool evalKTXFormat(
const Element& mipFormat,
const Element& texelFormat, ktx::Header& header);
524 static bool evalTextureFormat(
const ktx::Header& header, Element& mipFormat, Element& texelFormat);
525 static bool getCompressedFormat(khronos::gl::texture::InternalFormat format, Element& elFormat);
528 const TextureUsageType _usageType;
531 mutable Mutex _externalMutex;
532 mutable std::list<ExternalIdAndFence> _externalUpdates;
533 ExternalRecycler _externalRecycler;
536 std::weak_ptr<Texture> _fallback;
539 std::string _sourceHash;
540 std::unique_ptr< Storage > _storage;
545 Stamp _samplerStamp { 0 };
548 Element _texelFormat;
551 uint16 _height { 1 };
553 int _originalWidth { 0 };
554 int _originalHeight { 0 };
556 uint16 _numSamples { 1 };
559 uint16 _numSlices { 0 };
563 uint16 _maxMipLevel { 0 };
565 uint16 _minMip { 0 };
567 Type _type { TEX_1D };
571 SHPointer _irradiance;
572 bool _autoGenerateMips =
false;
573 bool _isIrradianceValid =
false;
574 bool _defined =
false;
575 bool _important =
false;
577 static TexturePointer create(TextureUsageType usageType, Type type,
const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, uint16 numMips,
const Sampler& sampler);
579 Size resize(Type type,
const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, uint16 numMips);
581 friend class Serializer;
582 friend class Deserializer;
585 typedef std::shared_ptr<Texture> TexturePointer;
586 typedef std::vector< TexturePointer > Textures;
592 typedef Resource::Size Size;
594 TexturePointer _texture = TexturePointer(NULL);
595 uint16 _subresource = 0;
596 Element _element = Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
600 TextureView(
const Element& element) :
605 TextureView(
Texture* newTexture,
const Element& element) :
606 _texture(newTexture),
610 TextureView(
const TexturePointer& texture, uint16 subresource,
const Element& element) :
612 _subresource(subresource),
616 TextureView(
const TexturePointer& texture, uint16 subresource, std::function<gpu::TexturePointer()> textureOperator =
nullptr) :
618 _subresource(subresource),
619 _textureOperator(textureOperator)
623 TextureView(
const TextureView& view) =
default;
624 TextureView& operator=(
const TextureView& view) =
default;
626 explicit operator bool()
const {
return bool(_texture); }
627 bool operator !()
const {
return (!_texture); }
629 bool isValid()
const {
return bool(_texture); }
631 bool isReference()
const {
return (
bool)_textureOperator; }
632 std::function<gpu::TexturePointer()> getTextureOperator()
const {
return _textureOperator; }
635 std::function<gpu::TexturePointer()> _textureOperator {
nullptr };
637 typedef std::vector<TextureView> TextureViews;
641 class TextureSource {
643 TextureSource(
const QUrl& url,
int type = 0) : _imageUrl(url), _type(type) {}
645 void setUrl(
const QUrl& url) { _imageUrl = url; }
646 const QUrl& getUrl()
const {
return _imageUrl; }
647 const gpu::TexturePointer getGPUTexture()
const;
648 void setType(
int type) { _type = type; }
649 int getType()
const {
return _type; }
651 void resetTexture(
const gpu::TexturePointer& texture);
652 void resetTextureOperator(
const std::function<gpu::TexturePointer()>& textureOperator);
654 bool isDefined()
const;
655 std::function<gpu::TexturePointer()> getTextureOperator()
const {
return _gpuTextureOperator; }
657 void setSampler(
const Sampler& sampler);
660 gpu::TexturePointer _gpuTexture;
661 std::function<gpu::TexturePointer()> _gpuTextureOperator {
nullptr };
662 mutable bool _locked {
false };
666 typedef std::shared_ptr< TextureSource > TextureSourcePointer;
670 Q_DECLARE_METATYPE(gpu::TexturePointer)
RAII tracker of advance position.
Definition: SerDes.h:594
Data deserializer.
Definition: SerDes.h:573
RAII tracker of advance position.
Definition: SerDes.h:82
Data serializer.
Definition: SerDes.h:61
Base class for resources.
Definition: ResourceCache.h:415
A simple object wrapper for an OpenGL texture.
Definition: material-networking/src/material-networking/TextureCache.h:39