From 47087add154867caae91939a283a9fbfd7a3b727 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Fri, 3 Mar 2017 08:58:55 -0800 Subject: [PATCH] Add support for fallback textures, throttling texture creation --- libraries/gpu-gl/src/gpu/gl45/GL45Backend.cpp | 6 +++ libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 1 + .../src/gpu/gl45/GL45BackendTexture.cpp | 30 ++++++------ .../gpu/gl45/GL45BackendVariableTexture.cpp | 3 ++ libraries/gpu/src/gpu/Texture.h | 4 ++ .../src/model-networking/TextureCache.cpp | 46 ++++++++++++++++++- .../src/model-networking/TextureCache.h | 1 + 7 files changed, 75 insertions(+), 16 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.cpp index f0ef2ac7a8..12c4b818f7 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.cpp @@ -18,6 +18,12 @@ Q_LOGGING_CATEGORY(gpugl45logging, "hifi.gpu.gl45") using namespace gpu; using namespace gpu::gl45; +void GL45Backend::recycle() const { + Parent::recycle(); + GL45VariableAllocationTexture::manageMemory(); + GL45VariableAllocationTexture::_frameTexturesCreated = 0; +} + void GL45Backend::do_draw(const Batch& batch, size_t paramOffset) { Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint; GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType]; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index cfdcc356a6..6a9811b055 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -147,6 +147,7 @@ public: using TransferQueue = std::queue>; static MemoryPressureState _memoryPressureState; protected: + static size_t _frameTexturesCreated; static std::atomic _memoryPressureStateStale; static std::list _memoryManagedTextures; static WorkQueue _transferQueue; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index d5ad0204bf..36aaf75e81 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -28,6 +28,7 @@ using namespace gpu::gl; using namespace gpu::gl45; #define SPARSE_PAGE_SIZE_OVERHEAD_ESTIMATE 1.3f +#define MAX_RESOURCE_TEXTURES_PER_FRAME 2 GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texturePointer) { if (!texturePointer) { @@ -57,19 +58,23 @@ GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texturePointer) { break; case TextureUsageType::RESOURCE: { - - GL45VariableAllocationTexture* varObject { nullptr }; + if (GL45VariableAllocationTexture::_frameTexturesCreated < MAX_RESOURCE_TEXTURES_PER_FRAME) { #if 0 - if (isTextureManagementSparseEnabled() && GL45Texture::isSparseEligible(texture)) { - varObject = new GL45SparseResourceTexture(shared_from_this(), texture); - } else { - varObject = new GL45ResourceTexture(shared_from_this(), texture); - } + if (isTextureManagementSparseEnabled() && GL45Texture::isSparseEligible(texture)) { + object = new GL45SparseResourceTexture(shared_from_this(), texture); + } else { + object = new GL45ResourceTexture(shared_from_this(), texture); + } #else - varObject = new GL45ResourceTexture(shared_from_this(), texture); + object = new GL45ResourceTexture(shared_from_this(), texture); #endif - GL45VariableAllocationTexture::addMemoryManagedTexture(texturePointer); - object = varObject; + GL45VariableAllocationTexture::addMemoryManagedTexture(texturePointer); + } else { + auto fallback = texturePointer->getFallbackTexture(); + if (fallback) { + object = static_cast(syncGPUObject(fallback)); + } + } break; } @@ -81,11 +86,6 @@ GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texturePointer) { return object; } -void GL45Backend::recycle() const { - Parent::recycle(); - GL45VariableAllocationTexture::manageMemory(); -} - void GL45Backend::initTextureManagementStage() { // enable the Sparse Texture on gl45 _textureManagement._sparseCapable = true; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp index 92251bd381..d54ad1ea4b 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp @@ -405,7 +405,10 @@ void GL45VariableAllocationTexture::manageMemory() { processWorkQueues(); } +size_t GL45VariableAllocationTexture::_frameTexturesCreated { 0 }; + GL45VariableAllocationTexture::GL45VariableAllocationTexture(const std::weak_ptr& backend, const Texture& texture) : GL45Texture(backend, texture) { + ++_frameTexturesCreated; } GL45VariableAllocationTexture::~GL45VariableAllocationTexture() { diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index d840687af2..9996026254 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -503,6 +503,9 @@ public: const Sampler& getSampler() const { return _sampler; } Stamp getSamplerStamp() const { return _samplerStamp; } + void setFallbackTexture(const TexturePointer& fallback) { _fallback = fallback; } + TexturePointer getFallbackTexture() const { return _fallback.lock(); } + void setExternalTexture(uint32 externalId, void* externalFence); void setExternalRecycler(const ExternalRecycler& recycler); ExternalRecycler getExternalRecycler() const; @@ -526,6 +529,7 @@ protected: ExternalRecycler _externalRecycler; + std::weak_ptr _fallback; // Not strictly necessary, but incredibly useful for debugging std::string _source; std::unique_ptr< Storage > _storage; diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 1f21e9e78d..f4473ceb39 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -186,6 +186,39 @@ NetworkTexturePointer TextureCache::getTexture(const QUrl& url, Type type, const return ResourceCache::getResource(url, QUrl(), &extra).staticCast(); } +gpu::TexturePointer getFallbackTextureForType(NetworkTexture::Type type) { + auto textureCache = DependencyManager::get(); + + gpu::TexturePointer result; + switch (type) { + case NetworkTexture::DEFAULT_TEXTURE: + case NetworkTexture::ALBEDO_TEXTURE: + case NetworkTexture::ROUGHNESS_TEXTURE: + case NetworkTexture::OCCLUSION_TEXTURE: + result = textureCache->getWhiteTexture(); + break; + + case NetworkTexture::NORMAL_TEXTURE: + result = textureCache->getBlueTexture(); + break; + + case NetworkTexture::EMISSIVE_TEXTURE: + case NetworkTexture::LIGHTMAP_TEXTURE: + result = textureCache->getBlackTexture(); + break; + + case NetworkTexture::BUMP_TEXTURE: + case NetworkTexture::SPECULAR_TEXTURE: + case NetworkTexture::GLOSS_TEXTURE: + case NetworkTexture::CUBE_TEXTURE: + case NetworkTexture::CUSTOM_TEXTURE: + case NetworkTexture::STRICT_TEXTURE: + default: + break; + } + return result; +} + NetworkTexture::TextureLoaderFunc getTextureLoaderForType(NetworkTexture::Type type, const QVariantMap& options = QVariantMap()) { @@ -299,6 +332,13 @@ NetworkTexture::TextureLoaderFunc NetworkTexture::getTextureLoader() const { return getTextureLoaderForType(_type); } +gpu::TexturePointer NetworkTexture::getFallbackTexture() const { + if (_type == CUSTOM_TEXTURE) { + return gpu::TexturePointer(); + } + return getFallbackTextureForType(_type); +} + class ImageReader : public QRunnable { public: @@ -428,7 +468,11 @@ void ImageReader::run() { auto url = _url.toString().toStdString(); PROFILE_RANGE_EX(resource_parse_image, __FUNCTION__, 0xffffff00, 0); - texture.reset(resource.dynamicCast()->getTextureLoader()(image, url)); + auto networkTexture = resource.dynamicCast(); + texture.reset(networkTexture->getTextureLoader()(image, url)); + if (texture) { + texture->setFallbackTexture(networkTexture->getFallbackTexture()); + } } // Ensure the resource has not been deleted diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index 749b5a2ebb..c77bafe447 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -75,6 +75,7 @@ public: Type getTextureType() const { return _type; } TextureLoaderFunc getTextureLoader() const; + gpu::TexturePointer getFallbackTexture() const; signals: void networkTextureCreated(const QWeakPointer& self);