Add support for fallback textures, throttling texture creation

This commit is contained in:
Bradley Austin Davis 2017-03-03 08:58:55 -08:00
parent 8db74413fd
commit 47087add15
7 changed files with 75 additions and 16 deletions

View file

@ -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];

View file

@ -147,6 +147,7 @@ public:
using TransferQueue = std::queue<std::unique_ptr<TransferJob>>;
static MemoryPressureState _memoryPressureState;
protected:
static size_t _frameTexturesCreated;
static std::atomic<bool> _memoryPressureStateStale;
static std::list<TextureWeakPointer> _memoryManagedTextures;
static WorkQueue _transferQueue;

View file

@ -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<GL45Texture*>(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;

View file

@ -405,7 +405,10 @@ void GL45VariableAllocationTexture::manageMemory() {
processWorkQueues();
}
size_t GL45VariableAllocationTexture::_frameTexturesCreated { 0 };
GL45VariableAllocationTexture::GL45VariableAllocationTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture) : GL45Texture(backend, texture) {
++_frameTexturesCreated;
}
GL45VariableAllocationTexture::~GL45VariableAllocationTexture() {

View file

@ -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<Texture> _fallback;
// Not strictly necessary, but incredibly useful for debugging
std::string _source;
std::unique_ptr< Storage > _storage;

View file

@ -186,6 +186,39 @@ NetworkTexturePointer TextureCache::getTexture(const QUrl& url, Type type, const
return ResourceCache::getResource(url, QUrl(), &extra).staticCast<NetworkTexture>();
}
gpu::TexturePointer getFallbackTextureForType(NetworkTexture::Type type) {
auto textureCache = DependencyManager::get<TextureCache>();
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<NetworkTexture>()->getTextureLoader()(image, url));
auto networkTexture = resource.dynamicCast<NetworkTexture>();
texture.reset(networkTexture->getTextureLoader()(image, url));
if (texture) {
texture->setFallbackTexture(networkTexture->getFallbackTexture());
}
}
// Ensure the resource has not been deleted

View file

@ -75,6 +75,7 @@ public:
Type getTextureType() const { return _type; }
TextureLoaderFunc getTextureLoader() const;
gpu::TexturePointer getFallbackTexture() const;
signals:
void networkTextureCreated(const QWeakPointer<NetworkTexture>& self);