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>
28 const int ABSOLUTE_MAX_TEXTURE_NUM_PIXELS = 8192 * 8192;
32 using KTXUniquePointer = std::unique_ptr<KTX>;
34 using KTXDescriptorPointer = std::unique_ptr<KTXDescriptor>;
37 using KeyValues = std::list<KeyValue>;
40 namespace khronos {
namespace gl {
namespace texture {
41 enum class InternalFormat: uint32_t;
46 enum class BackendTarget {
52 const std::string SOURCE_HASH_KEY {
"hifi.sourceHash" };
54 const uint8 SOURCE_HASH_BYTES = 16;
59 class SphericalHarmonics {
61 glm::vec3 L00 ;
float spare0;
62 glm::vec3 L1m1 ;
float spare1;
63 glm::vec3 L10 ;
float spare2;
64 glm::vec3 L11 ;
float spare3;
65 glm::vec3 L2m2 ;
float spare4;
66 glm::vec3 L2m1 ;
float spare5;
67 glm::vec3 L20 ;
float spare6;
68 glm::vec3 L21 ;
float spare7;
69 glm::vec3 L22 ;
float spare8;
71 static const int NUM_COEFFICIENTS = 9;
88 void assignPreset(
int p);
90 void evalFromTexture(
const Texture& texture, gpu::BackendTarget target);
92 typedef std::shared_ptr< SphericalHarmonics > SHPointer;
99 FILTER_MIN_POINT_MAG_LINEAR,
100 FILTER_MIN_LINEAR_MAG_POINT,
101 FILTER_MIN_MAG_LINEAR,
103 FILTER_MIN_MAG_MIP_POINT,
104 FILTER_MIN_MAG_POINT_MIP_LINEAR,
105 FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT,
106 FILTER_MIN_POINT_MAG_MIP_LINEAR,
107 FILTER_MIN_LINEAR_MAG_MIP_POINT,
108 FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR,
109 FILTER_MIN_MAG_LINEAR_MIP_POINT,
110 FILTER_MIN_MAG_MIP_LINEAR,
126 static const uint8 MAX_MIP_LEVEL = 0xFF;
130 glm::vec4 _borderColor{ 1.0f };
131 uint32 _maxAnisotropy = 16;
133 uint8 _filter = FILTER_MIN_MAG_POINT;
134 uint8 _comparisonFunc = ALWAYS;
136 uint8 _wrapModeU = WRAP_REPEAT;
137 uint8 _wrapModeV = WRAP_REPEAT;
138 uint8 _wrapModeW = WRAP_REPEAT;
140 uint8 _mipOffset = 0;
142 uint8 _maxMip = MAX_MIP_LEVEL;
145 Desc(
const Filter filter,
const WrapMode wrap = WRAP_REPEAT) : _filter(filter), _wrapModeU(wrap), _wrapModeV(wrap), _wrapModeW(wrap) {}
147 bool operator==(
const Desc& other)
const {
148 return _borderColor == other._borderColor &&
149 _maxAnisotropy == other._maxAnisotropy &&
150 _filter == other._filter &&
151 _comparisonFunc == other._comparisonFunc &&
152 _wrapModeU == other._wrapModeU &&
153 _wrapModeV == other._wrapModeV &&
154 _wrapModeW == other._wrapModeW &&
155 _mipOffset == other._mipOffset &&
156 _minMip == other._minMip &&
157 _maxMip == other._maxMip;
162 Sampler(
const Filter filter,
const WrapMode wrap = WRAP_REPEAT) : _desc(filter, wrap) {}
163 Sampler(
const Desc& desc) : _desc(desc) {}
166 const glm::vec4& getBorderColor()
const {
return _desc._borderColor; }
168 uint32 getMaxAnisotropy()
const {
return _desc._maxAnisotropy; }
170 WrapMode getWrapModeU()
const {
return WrapMode(_desc._wrapModeU); }
171 WrapMode getWrapModeV()
const {
return WrapMode(_desc._wrapModeV); }
172 WrapMode getWrapModeW()
const {
return WrapMode(_desc._wrapModeW); }
174 Filter getFilter()
const {
return Filter(_desc._filter); }
175 ComparisonFunction getComparisonFunction()
const {
return ComparisonFunction(_desc._comparisonFunc); }
176 bool doComparison()
const {
return getComparisonFunction() != ALWAYS; }
178 uint8 getMipOffset()
const {
return _desc._mipOffset; }
179 uint8 getMinMip()
const {
return _desc._minMip; }
180 uint8 getMaxMip()
const {
return _desc._maxMip; }
182 const Desc& getDesc()
const {
return _desc; }
184 bool operator==(
const Sampler& other)
const {
185 return _desc == other._desc;
187 bool operator!=(
const Sampler& other)
const {
188 return !(*
this == other);
193 friend class Deserializer;
196 enum class TextureUsageType : uint8 {
204 static ContextMetricCount _textureCPUCount;
205 static ContextMetricSize _textureCPUMemSize;
207 static std::atomic<Size> _allowedCPUMemoryUsage;
208 static std::atomic<bool> _enableSparseTextures;
209 static void updateTextureCPUMemoryUsage(Size prevObjectSize, Size newObjectSize);
212 static const uint32_t CUBE_FACE_COUNT { 6 };
213 static uint32_t getTextureCPUCount();
214 static Size getTextureCPUMemSize();
216 static Size getAllowedGPUMemoryUsage();
217 static void setAllowedGPUMemoryUsage(Size size);
219 static bool getEnableSparseTextures();
220 static void setEnableSparseTextures(
bool enabled);
222 using ExternalRecycler = std::function<void(uint32,
void*)>;
223 using ExternalIdAndFence = std::pair<uint32, void*>;
224 using ExternalUpdates = std::list<ExternalIdAndFence>;
236 typedef std::bitset<NUM_FLAGS> Flags;
241 Usage() : _flags(0) {}
242 Usage(
const Flags& flags) : _flags(flags) {}
244 bool operator== (
const Usage& rhs)
const {
return _flags == rhs._flags; }
245 bool operator!= (
const Usage& rhs)
const {
return _flags != rhs._flags; }
253 Usage build()
const {
return Usage(_flags); }
255 Builder& withColor() { _flags.set(COLOR);
return (*
this); }
256 Builder& withNormal() { _flags.set(NORMAL);
return (*
this); }
257 Builder& withAlpha() { _flags.set(ALPHA);
return (*
this); }
258 Builder& withAlphaMask() { _flags.set(ALPHA_MASK);
return (*
this); }
260 Usage(
const Builder& builder) : Usage(builder._flags) {}
262 bool isColor()
const {
return _flags[COLOR]; }
263 bool isNormal()
const {
return _flags[NORMAL]; }
265 bool isAlpha()
const {
return _flags[ALPHA]; }
266 bool isAlphaMask()
const {
return _flags[ALPHA_MASK]; }
268 bool operator==(
const Usage& usage) {
return (_flags == usage._flags); }
269 bool operator!=(
const Usage& usage) {
return (_flags != usage._flags); }
283 CUBE_FACE_RIGHT_POS_X = 0,
284 CUBE_FACE_LEFT_NEG_X,
286 CUBE_FACE_BOTTOM_NEG_Y,
287 CUBE_FACE_BACK_POS_Z,
288 CUBE_FACE_FRONT_NEG_Z,
294 static const uint32 PACKING_SIZE = 4;
295 static uint8 evalPaddingNumBytes(Size byteSize) {
return (uint8) (3 - (byteSize + 3) % PACKING_SIZE); }
296 static Size evalPaddedSize(Size byteSize) {
return byteSize + (Size) evalPaddingNumBytes(byteSize); }
299 using PixelsPointer = storage::StoragePointer;
303 virtual ~Storage() {}
305 virtual void reset() = 0;
306 virtual PixelsPointer getMipFace(uint16 level, uint8 face = 0)
const = 0;
307 virtual Size getMipFaceSize(uint16 level, uint8 face = 0)
const = 0;
308 virtual void assignMipData(uint16 level,
const storage::StoragePointer& storage) = 0;
309 virtual void assignMipFaceData(uint16 level, uint8 face,
const storage::StoragePointer& storage) = 0;
310 virtual bool isMipAvailable(uint16 level, uint8 face = 0)
const = 0;
311 virtual uint16 minAvailableMipLevel()
const {
return 0; }
312 Texture::Type getType()
const {
return _type; }
314 Stamp getStamp()
const {
return _stamp; }
315 Stamp bumpStamp() {
return ++_stamp; }
317 void setFormat(
const Element& format) { _format = format; }
318 Element getFormat()
const {
return _format; }
323 Texture::Type _type { Texture::TEX_2D };
325 virtual void assignTexture(
Texture* tex);
326 const Texture* getTexture()
const {
return _texture; }
330 class MemoryStorage :
public Storage {
332 void reset()
override;
333 PixelsPointer getMipFace(uint16 level, uint8 face = 0)
const override;
334 Size getMipFaceSize(uint16 level, uint8 face = 0)
const override;
335 void assignMipData(uint16 level,
const storage::StoragePointer& storage)
override;
336 void assignMipFaceData(uint16 level, uint8 face,
const storage::StoragePointer& storage)
override;
337 bool isMipAvailable(uint16 level, uint8 face = 0)
const override;
340 void allocateMip(uint16 level);
341 std::vector<std::vector<PixelsPointer>> _mips;
344 class KtxStorage :
public Storage {
346 KtxStorage(
const storage::StoragePointer& storage);
347 KtxStorage(
const std::string& filename);
348 KtxStorage(
const cache::FilePointer& file);
349 PixelsPointer getMipFace(uint16 level, uint8 face = 0)
const override;
350 Size getMipFaceSize(uint16 level, uint8 face = 0)
const override;
351 bool isMipAvailable(uint16 level, uint8 face = 0)
const override;
352 void assignMipData(uint16 level,
const storage::StoragePointer& storage)
override;
353 void assignMipFaceData(uint16 level, uint8 face,
const storage::StoragePointer& storage)
override;
354 uint16 minAvailableMipLevel()
const override;
356 void reset()
override { }
359 static void releaseOpenKtxFiles();
362 std::shared_ptr<storage::FileStorage> maybeOpenFile()
const;
364 mutable std::shared_ptr<std::mutex> _cacheFileMutex { std::make_shared<std::mutex>() };
365 mutable std::weak_ptr<storage::FileStorage> _cacheFile;
367 static std::vector<std::pair<std::shared_ptr<storage::FileStorage>, std::shared_ptr<std::mutex>>> _cachedKtxFiles;
368 static std::mutex _cachedKtxFilesMutex;
370 storage::StoragePointer _storage;
371 std::string _filename;
372 cache::FilePointer _cacheEntry;
373 std::atomic<uint8_t> _minMipLevelAvailable;
374 size_t _offsetToMinMipKV;
376 ktx::KTXDescriptorPointer _ktxDescriptor;
378 friend class Serializer;
379 friend class Deserializer;
382 uint16 minAvailableMipLevel()
const {
return _storage->minAvailableMipLevel(); };
384 static const uint16 MAX_NUM_MIPS = 0;
385 static const uint16 SINGLE_MIP = 1;
386 static TexturePointer create1D(
const Element& texelFormat, uint16 width, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
387 static TexturePointer create2D(
const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
388 static TexturePointer create2DArray(
const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
389 static TexturePointer create3D(
const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
390 static TexturePointer createCube(
const Element& texelFormat, uint16 width, uint16 numMips = 1,
const Sampler& sampler = Sampler());
391 static TexturePointer createRenderBuffer(
const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
392 static TexturePointer createRenderBufferMultisample(
const Element& texelFormat, uint16 width, uint16 height, uint16 numSamples,
const Sampler& sampler = Sampler());
393 static TexturePointer createRenderBufferArray(
const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
394 static TexturePointer createRenderBufferMultisampleArray(
const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numSamples,
const Sampler& sampler = Sampler());
395 static TexturePointer createStrict(
const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP,
const Sampler& sampler = Sampler());
396 static TexturePointer createExternal(
const ExternalRecycler& recycler,
const Sampler& sampler = Sampler());
399 bool isDefined()
const {
return _defined; }
401 Texture(TextureUsageType usageType);
404 Stamp getStamp()
const {
return _stamp; }
405 Stamp getDataStamp()
const {
return _storage->getStamp(); }
409 Size getSize()
const override {
return _size; }
412 Type getType()
const {
return _type; }
413 TextureUsageType getUsageType()
const {
return _usageType; }
415 bool isColorRenderTarget()
const;
416 bool isDepthStencilRenderTarget()
const;
418 Element getTexelFormat()
const {
return _texelFormat; }
420 void setSize(
int width,
int height);
421 Vec3u getDimensions()
const {
return Vec3u(_width, _height, _depth); }
422 uint16 getWidth()
const {
return _width; }
423 uint16 getHeight()
const {
return _height; }
424 uint16 getDepth()
const {
return _depth; }
426 void setOriginalSize(
int width,
int height);
427 int getOriginalWidth()
const {
return _originalWidth; }
428 int getOriginalHeight()
const {
return _originalHeight; }
433 static uint8 NUM_FACES_PER_TYPE[NUM_TYPES];
434 uint8 getNumFaces()
const {
return NUM_FACES_PER_TYPE[getType()]; }
439 bool isArray()
const {
return _numSlices > 0; }
440 uint16 getNumSlices()
const {
return (isArray() ? _numSlices : 1); }
442 uint16 getNumSamples()
const {
return _numSamples; }
444 static uint16 evalNumSamplesUsed(uint16 numSamplesTried);
445 bool isMultisample()
const {
return _numSamples > 1; }
449 uint16 getMaxMip()
const {
return _maxMipLevel; }
450 uint16 getNumMips()
const {
return _maxMipLevel + 1; }
456 static uint16 evalDimMaxNumMips(uint16 size);
460 uint16 evalMaxNumMips()
const;
461 static uint16 evalMaxNumMips(
const Vec3u& dimensions);
466 static uint16 safeNumMips(uint16 askedNumMips, uint16 maxMips);
469 uint16 safeNumMips(uint16 askedNumMips)
const;
475 Vec3u evalMipDimensions(uint16 level)
const;
476 uint16 evalMipWidth(uint16 level)
const {
return std::max(_width >> level, 1); }
477 uint16 evalMipHeight(uint16 level)
const {
return std::max(_height >> level, 1); }
478 uint16 evalMipDepth(uint16 level)
const {
return std::max(_depth >> level, 1); }
484 static uint16 evalTiledPadding(uint16 length,
int tile) {
int tileMinusOne = (tile - 1);
return (tileMinusOne - (length + tileMinusOne) % tile); }
485 static uint16 evalTiledLength(uint16 length,
int tile) {
return length / tile + (evalTiledPadding(length, tile) != 0); }
486 static uint16 evalTiledWidth(uint16 width,
int tileX) {
return evalTiledLength(width, tileX); }
487 static uint16 evalTiledHeight(uint16 height,
int tileY) {
return evalTiledLength(height, tileY); }
488 static Size evalLineSize(uint16 width,
const Element& format) {
return evalPaddedSize(evalTiledWidth(width, format.getTile().x) * format.getSize()); }
489 static Size evalSurfaceSize(uint16 width, uint16 height,
const Element& format) {
return evalLineSize(width, format) * evalTiledHeight(height, format.getTile().x); }
492 Size evalStoredMipLineSize(uint16 level,
const Element& format)
const {
return evalLineSize(evalMipWidth(level), format); }
493 Size evalStoredMipSurfaceSize(uint16 level,
const Element& format)
const {
return evalSurfaceSize(evalMipWidth(level), evalMipHeight(level), format); }
494 Size evalStoredMipFaceSize(uint16 level,
const Element& format)
const {
return evalStoredMipSurfaceSize(level, format) * evalMipDepth(level); }
495 Size evalStoredMipSize(uint16 level,
const Element& format)
const {
return evalStoredMipFaceSize(level, format) * getNumFaces(); }
498 Size evalMipLineSize(uint16 level)
const {
return evalStoredMipLineSize(level, getTexelFormat()); }
499 Size evalMipSurfaceSize(uint16 level)
const {
return evalStoredMipSurfaceSize(level, getTexelFormat()); }
500 Size evalMipFaceSize(uint16 level)
const {
return evalStoredMipFaceSize(level, getTexelFormat()); }
501 Size evalMipSize(uint16 level)
const {
return evalStoredMipSize(level, getTexelFormat()); }
504 Size evalTotalSize(uint16 startingMip = 0)
const;
507 uint32 evalMipFaceNumTexels(uint16 level)
const {
return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); }
508 uint32 evalMipNumTexels(uint16 level)
const {
return evalMipFaceNumTexels(level) * getNumFaces(); }
511 const std::string& source()
const {
return _source; }
512 void setSource(
const std::string& source) { _source = source; }
513 const std::string& sourceHash()
const {
return _sourceHash; }
514 void setSourceHash(
const std::string& sourceHash) { _sourceHash = sourceHash; }
517 bool setMinMip(uint16 newMinMip);
518 bool incremementMinMip(uint16 count = 1);
519 uint16 getMinMip()
const {
return _minMip; }
520 uint16 usedMipLevels()
const {
return (getNumMips() - _minMip); }
525 void setAutoGenerateMips(
bool enable);
526 bool isAutogenerateMips()
const {
return _autoGenerateMips; }
531 void setStoredMipFormat(
const Element& format);
532 Element getStoredMipFormat()
const;
539 void assignStoredMip(uint16 level, Size size,
const Byte* bytes);
540 void assignStoredMipFace(uint16 level, uint8 face, Size size,
const Byte* bytes);
542 void assignStoredMip(uint16 level, storage::StoragePointer& storage);
543 void assignStoredMipFace(uint16 level, uint8 face, storage::StoragePointer& storage);
546 const PixelsPointer accessStoredMipFace(uint16 level, uint8 face = 0)
const {
return _storage->getMipFace(level, face); }
547 bool isStoredMipFaceAvailable(uint16 level, uint8 face = 0)
const;
548 Size getStoredMipFaceSize(uint16 level, uint8 face = 0)
const {
return _storage->getMipFaceSize(level, face); }
549 Size getStoredMipSize(uint16 level)
const;
550 Size getStoredSize()
const;
552 void setStorage(std::unique_ptr<Storage>& newStorage);
553 void setKtxBacking(
const storage::StoragePointer& storage);
554 void setKtxBacking(
const std::string& filename);
555 void setKtxBacking(
const cache::FilePointer& cacheEntry);
558 void setUsage(
const Usage& usage) { _usage = usage; }
559 Usage getUsage()
const {
return _usage; }
562 bool generateIrradiance(gpu::BackendTarget target);
563 const SHPointer& getIrradiance(uint16 slice = 0)
const {
return _irradiance; }
564 void overrideIrradiance(SHPointer irradiance) { _irradiance = irradiance; }
565 bool isIrradianceValid()
const {
return _isIrradianceValid; }
568 void setSampler(
const Sampler& sampler);
569 const Sampler& getSampler()
const {
return _sampler; }
570 Stamp getSamplerStamp()
const {
return _samplerStamp; }
572 void setFallbackTexture(
const TexturePointer& fallback) { _fallback = fallback; }
573 TexturePointer getFallbackTexture()
const {
return _fallback.lock(); }
575 void setExternalTexture(uint32 externalId,
void* externalFence);
576 void setExternalRecycler(
const ExternalRecycler& recycler);
577 ExternalRecycler getExternalRecycler()
const;
579 bool getImportant()
const {
return _important; }
580 void setImportant(
bool important) { _important = important; }
582 const GPUObjectPointer gpuObject {};
584 ExternalUpdates getUpdates()
const;
587 static ktx::KTXUniquePointer serialize(
const Texture& texture,
const glm::ivec2& originalSize);
589 static std::pair<TexturePointer, glm::ivec2> build(
const ktx::KTXDescriptor& descriptor);
590 static std::pair<TexturePointer, glm::ivec2> unserialize(
const std::string& ktxFile);
591 static std::pair<TexturePointer, glm::ivec2> unserialize(
const cache::FilePointer& cacheEntry,
const std::string& source = std::string());
593 static bool evalKTXFormat(
const Element& mipFormat,
const Element& texelFormat, ktx::Header& header);
594 static bool evalTextureFormat(
const ktx::Header& header, Element& mipFormat, Element& texelFormat);
595 static bool getCompressedFormat(khronos::gl::texture::InternalFormat format, Element& elFormat);
598 const TextureUsageType _usageType;
601 mutable Mutex _externalMutex;
602 mutable std::list<ExternalIdAndFence> _externalUpdates;
603 ExternalRecycler _externalRecycler;
606 std::weak_ptr<Texture> _fallback;
609 std::string _sourceHash;
610 std::unique_ptr< Storage > _storage;
615 Stamp _samplerStamp { 0 };
618 Element _texelFormat;
621 uint16 _height { 1 };
623 int _originalWidth { 0 };
624 int _originalHeight { 0 };
626 uint16 _numSamples { 1 };
629 uint16 _numSlices { 0 };
633 uint16 _maxMipLevel { 0 };
635 uint16 _minMip { 0 };
637 Type _type { TEX_1D };
641 SHPointer _irradiance;
642 bool _autoGenerateMips =
false;
643 bool _isIrradianceValid =
false;
644 bool _defined =
false;
645 bool _important =
false;
647 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);
649 Size resize(Type type,
const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, uint16 numMips);
651 friend class Serializer;
652 friend class Deserializer;
655 typedef std::shared_ptr<Texture> TexturePointer;
656 typedef std::vector< TexturePointer > Textures;
662 typedef Resource::Size Size;
664 TexturePointer _texture = TexturePointer(NULL);
665 uint16 _subresource = 0;
666 Element _element = Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
670 TextureView(
const Element& element) :
675 TextureView(
Texture* newTexture,
const Element& element) :
676 _texture(newTexture),
680 TextureView(
const TexturePointer& texture, uint16 subresource,
const Element& element) :
682 _subresource(subresource),
686 TextureView(
const TexturePointer& texture, uint16 subresource, std::function<gpu::TexturePointer()> textureOperator =
nullptr) :
688 _subresource(subresource),
689 _textureOperator(textureOperator)
693 TextureView(
const TextureView& view) =
default;
694 TextureView& operator=(
const TextureView& view) =
default;
696 explicit operator bool()
const {
return bool(_texture); }
697 bool operator !()
const {
return (!_texture); }
699 bool isValid()
const {
return bool(_texture); }
701 bool isReference()
const {
return (
bool)_textureOperator; }
702 std::function<gpu::TexturePointer()> getTextureOperator()
const {
return _textureOperator; }
705 std::function<gpu::TexturePointer()> _textureOperator {
nullptr };
707 typedef std::vector<TextureView> TextureViews;
711 class TextureSource {
713 TextureSource(
const QUrl& url,
int type = 0) : _imageUrl(url), _type(type) {}
715 void setUrl(
const QUrl& url) { _imageUrl = url; }
716 const QUrl& getUrl()
const {
return _imageUrl; }
717 const gpu::TexturePointer getGPUTexture()
const;
718 void setType(
int type) { _type = type; }
719 int getType()
const {
return _type; }
721 void resetTexture(
const gpu::TexturePointer& texture);
722 void resetTextureOperator(
const std::function<gpu::TexturePointer()>& textureOperator);
724 bool isDefined()
const;
725 std::function<gpu::TexturePointer()> getTextureOperator()
const {
return _gpuTextureOperator; }
728 gpu::TexturePointer _gpuTexture;
729 std::function<gpu::TexturePointer()> _gpuTextureOperator {
nullptr };
730 mutable bool _locked {
false };
734 typedef std::shared_ptr< TextureSource > TextureSourcePointer;
739 template<>
struct hash<gpu::Sampler> {
740 size_t operator()(
const gpu::Sampler& sampler)
const noexcept {
742 const auto& desc = sampler.getDesc();
743 hash_combine(result, desc._comparisonFunc, desc._filter, desc._maxAnisotropy, desc._maxMip, desc._minMip, desc._wrapModeU, desc._wrapModeV, desc._wrapModeW);
749 Q_DECLARE_METATYPE(gpu::TexturePointer)
Base class for resources.
Definition: ResourceCache.h:409
A simple object wrapper for an OpenGL texture.
Definition: material-networking/src/material-networking/TextureCache.h:39