First pass at using compressed format when uploading textures

This commit is contained in:
samcake 2016-03-31 19:27:35 -07:00
parent 74633ca8c8
commit 9d1f91fa19
12 changed files with 118 additions and 21 deletions

View file

@ -108,7 +108,18 @@ Item {
prop: "textureGPUMemoryUsage",
label: "GPU",
color: "#1AC567"
},
{
prop: "textureGPUVirtualMemoryUsage",
label: "GPU Virtual",
color: "#9495FF"
},
{
prop: "frameTextureMemoryUsage",
label: "Frame",
color: "#E2334D"
}
]
}
@ -186,7 +197,7 @@ Item {
object: Render.getConfig("DrawLight"),
prop: "numDrawn",
label: "Lights",
color: "#E2334D"
color: "#FED959"
}
]
}

View file

@ -114,6 +114,7 @@ std::atomic<Buffer::Size> Context::_bufferGPUMemoryUsage{ 0 };
std::atomic<uint32_t> Context::_textureGPUCount{ 0 };
std::atomic<Texture::Size> Context::_textureGPUMemoryUsage{ 0 };
std::atomic<Texture::Size> Context::_textureGPUVirtualMemoryUsage{ 0 };
void Context::incrementBufferGPUCount() {
_bufferGPUCount++;
@ -149,6 +150,17 @@ void Context::updateTextureGPUMemoryUsage(Size prevObjectSize, Size newObjectSiz
}
}
void Context::updateTextureGPUVirtualMemoryUsage(Size prevObjectSize, Size newObjectSize) {
if (prevObjectSize == newObjectSize) {
return;
}
if (newObjectSize > prevObjectSize) {
_textureGPUVirtualMemoryUsage.fetch_add(newObjectSize - prevObjectSize);
} else {
_textureGPUVirtualMemoryUsage.fetch_sub(prevObjectSize - newObjectSize);
}
}
uint32_t Context::getBufferGPUCount() {
return _bufferGPUCount.load();
}
@ -165,10 +177,15 @@ Context::Size Context::getTextureGPUMemoryUsage() {
return _textureGPUMemoryUsage.load();
}
Context::Size Context::getTextureGPUVirtualMemoryUsage() {
return _textureGPUVirtualMemoryUsage.load();
}
void Backend::incrementBufferGPUCount() { Context::incrementBufferGPUCount(); }
void Backend::decrementBufferGPUCount() { Context::decrementBufferGPUCount(); }
void Backend::updateBufferGPUMemoryUsage(Resource::Size prevObjectSize, Resource::Size newObjectSize) { Context::updateBufferGPUMemoryUsage(prevObjectSize, newObjectSize); }
void Backend::incrementTextureGPUCount() { Context::incrementTextureGPUCount(); }
void Backend::decrementTextureGPUCount() { Context::decrementTextureGPUCount(); }
void Backend::updateTextureGPUMemoryUsage(Resource::Size prevObjectSize, Resource::Size newObjectSize) { Context::updateTextureGPUMemoryUsage(prevObjectSize, newObjectSize); }
void Backend::updateTextureGPUVirtualMemoryUsage(Resource::Size prevObjectSize, Resource::Size newObjectSize) { Context::updateTextureGPUVirtualMemoryUsage(prevObjectSize, newObjectSize); }

View file

@ -34,6 +34,7 @@ public:
int _ISNumIndexBufferChanges = 0;
int _RSNumTextureBounded = 0;
int _RSAmountTextureMemoryBounded = 0;
int _DSNumAPIDrawcalls = 0;
int _DSNumDrawcalls = 0;
@ -128,6 +129,7 @@ public:
static void incrementTextureGPUCount();
static void decrementTextureGPUCount();
static void updateTextureGPUMemoryUsage(Resource::Size prevObjectSize, Resource::Size newObjectSize);
static void updateTextureGPUVirtualMemoryUsage(Resource::Size prevObjectSize, Resource::Size newObjectSize);
protected:
StereoState _stereo;
@ -177,6 +179,7 @@ public:
static uint32_t getTextureGPUCount();
static Size getTextureGPUMemoryUsage();
static Size getTextureGPUVirtualMemoryUsage();
protected:
Context(const Context& context);
@ -202,6 +205,7 @@ protected:
static void incrementTextureGPUCount();
static void decrementTextureGPUCount();
static void updateTextureGPUMemoryUsage(Size prevObjectSize, Size newObjectSize);
static void updateTextureGPUVirtualMemoryUsage(Size prevObjectSize, Size newObjectSize);
// Buffer and Texture Counters
static std::atomic<uint32_t> _bufferGPUCount;
@ -209,6 +213,7 @@ protected:
static std::atomic<uint32_t> _textureGPUCount;
static std::atomic<Size> _textureGPUMemoryUsage;
static std::atomic<Size> _textureGPUVirtualMemoryUsage;
friend class Backend;
};

View file

@ -192,6 +192,13 @@ enum Semantic {
SRGBA,
SBGRA,
COMPRESSED_R,
COMPRESSED_RGB,
COMPRESSED_RGBA,
COMPRESSED_SRGB,
COMPRESSED_SRGBA,
R11G11B10,
UNIFORM,

View file

@ -83,11 +83,17 @@ public:
GLTexture();
~GLTexture();
void setSize(GLuint size);
GLuint size() const { return _size; }
GLuint virtualSize() const { return _virtualSize; }
void updateSize(GLuint virtualSize);
private:
GLuint _size;
void setSize(GLuint size);
void setVirtualSize(GLuint size);
GLuint _size; // true size as reported by the gl api
GLuint _virtualSize; // theorical size as expected
};
static GLTexture* syncGPUObject(const Texture& texture);
static GLuint getTextureID(const TexturePointer& texture, bool sync = true);

View file

@ -266,6 +266,8 @@ void GLBackend::do_setResourceTexture(Batch& batch, size_t paramOffset) {
_resource._textures[slot] = resourceTexture;
_stats._RSAmountTextureMemoryBounded += object->size();
} else {
releaseResourceTexture(slot);
return;

View file

@ -18,7 +18,8 @@ GLBackend::GLTexture::GLTexture() :
_contentStamp(0),
_texture(0),
_target(GL_TEXTURE_2D),
_size(0)
_size(0),
_virtualSize(0)
{
Backend::incrementTextureGPUCount();
}
@ -28,6 +29,7 @@ GLBackend::GLTexture::~GLTexture() {
glDeleteTextures(1, &_texture);
}
Backend::updateTextureGPUMemoryUsage(_size, 0);
Backend::updateTextureGPUVirtualMemoryUsage(_virtualSize, 0);
Backend::decrementTextureGPUCount();
}
@ -36,6 +38,25 @@ void GLBackend::GLTexture::setSize(GLuint size) {
_size = size;
}
void GLBackend::GLTexture::setVirtualSize(GLuint size) {
Backend::updateTextureGPUVirtualMemoryUsage(_virtualSize, size);
_virtualSize = size;
}
void GLBackend::GLTexture::updateSize(GLuint virtualSize) {
setVirtualSize(virtualSize);
GLint gpuSize{ 0 };
glGetTexLevelParameteriv(_target, 0, GL_TEXTURE_COMPRESSED, &gpuSize);
if (gpuSize) {
glGetTexLevelParameteriv(_target, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &gpuSize);
setSize(gpuSize);
} else {
setSize(virtualSize);
}
}
class GLTexelFormat {
public:
GLenum internalFormat;
@ -56,6 +77,11 @@ public:
case gpu::RGBA:
texel.internalFormat = GL_RED;
break;
case gpu::COMPRESSED_R:
texel.internalFormat = GL_COMPRESSED_RED_RGTC1;
break;
case gpu::DEPTH:
texel.internalFormat = GL_DEPTH_COMPONENT;
break;
@ -96,6 +122,12 @@ public:
case gpu::RGBA:
texel.internalFormat = GL_RGB;
break;
case gpu::COMPRESSED_RGB:
texel.internalFormat = GL_COMPRESSED_RGB;
break;
case gpu::COMPRESSED_SRGB:
texel.internalFormat = GL_COMPRESSED_SRGB;
break;
default:
qCDebug(gpulogging) << "Unknown combination of texel format";
}
@ -133,6 +165,13 @@ public:
case gpu::SRGBA:
texel.internalFormat = GL_SRGB_ALPHA;
break;
case gpu::COMPRESSED_RGBA:
texel.internalFormat = GL_COMPRESSED_RGBA;
break;
case gpu::COMPRESSED_SRGBA:
texel.internalFormat = GL_COMPRESSED_SRGB_ALPHA;
break;
default:
qCDebug(gpulogging) << "Unknown combination of texel format";
}
@ -452,15 +491,15 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
object->_target = GL_TEXTURE_2D;
syncSampler(texture.getSampler(), texture.getType(), object);
object->_target = GL_TEXTURE_2D;
syncSampler(texture.getSampler(), texture.getType(), object);
// At this point the mip piels have been loaded, we can notify
texture.notifyMipFaceGPULoaded(0, 0);
object->_contentStamp = texture.getDataStamp();
object->updateSize((GLuint)texture.evalTotalSize());
}
} else {
const GLvoid* bytes = 0;
@ -493,7 +532,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
object->_storageStamp = texture.getStamp();
object->_contentStamp = texture.getDataStamp();
object->setSize((GLuint)texture.getSize());
object->updateSize((GLuint)texture.evalTotalSize());
}
glBindTexture(GL_TEXTURE_2D, boundTex);
@ -539,6 +578,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
object->_contentStamp = texture.getDataStamp();
object->updateSize((GLuint)texture.evalTotalSize());
} else {
glBindTexture(GL_TEXTURE_CUBE_MAP, object->_texture);
@ -571,7 +611,7 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
object->_storageStamp = texture.getStamp();
object->_contentStamp = texture.getDataStamp();
object->setSize((GLuint)texture.getSize());
object->updateSize((GLuint)texture.evalTotalSize());
}
glBindTexture(GL_TEXTURE_CUBE_MAP, boundTex);

View file

@ -46,10 +46,13 @@ uint32_t Texture::getTextureGPUCount() {
Texture::Size Texture::getTextureGPUMemoryUsage() {
return Context::getTextureGPUMemoryUsage();
}
uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = {1, 1, 1, 6};
Texture::Size Texture::getTextureGPUVirtualMemoryUsage() {
return Context::getTextureGPUVirtualMemoryUsage();
}
uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = { 1, 1, 1, 6 };
Texture::Pixels::Pixels(const Element& format, Size size, const Byte* bytes) :
_format(format),

View file

@ -146,6 +146,7 @@ public:
static Size getTextureCPUMemoryUsage();
static uint32_t getTextureGPUCount();
static Size getTextureGPUMemoryUsage();
static Size getTextureGPUVirtualMemoryUsage();
class Usage {
public:

View file

@ -94,10 +94,10 @@ gpu::Texture* TextureUsage::create2DTextureFromImage(const QImage& srcImage, con
// bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
bool isLinearRGB = false; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::COMPRESSED_SRGB));
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
if (image.hasAlphaChannel()) {
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::COMPRESSED_SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
}
@ -264,7 +264,7 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromImage(const QImage& srcIma
gpu::Texture* theTexture = nullptr;
if ((image.width() > 0) && (image.height() > 0)) {
gpu::Element formatGPU = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB);
gpu::Element formatGPU = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::COMPRESSED_R);
gpu::Element formatMip = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB);
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
@ -297,7 +297,7 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromGlossImage(const QImage& s
gpu::Texture* theTexture = nullptr;
if ((image.width() > 0) && (image.height() > 0)) {
gpu::Element formatGPU = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB);
gpu::Element formatGPU = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::COMPRESSED_R);
gpu::Element formatMip = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB);
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
@ -327,7 +327,7 @@ gpu::Texture* TextureUsage::createMetallicTextureFromImage(const QImage& srcImag
gpu::Texture* theTexture = nullptr;
if ((image.width() > 0) && (image.height() > 0)) {
gpu::Element formatGPU = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB);
gpu::Element formatGPU = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::COMPRESSED_R);
gpu::Element formatMip = gpu::Element(gpu::SCALAR, gpu::NUINT8, gpu::RGB);
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
@ -446,10 +446,10 @@ gpu::Texture* TextureUsage::createCubeTextureFromImage(const QImage& srcImage, c
// bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
bool isLinearRGB = false; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::COMPRESSED_SRGB));
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
if (image.hasAlphaChannel()) {
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::COMPRESSED_SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
}
@ -669,10 +669,10 @@ gpu::Texture* TextureUsage::createLightmapTextureFromImage(const QImage& srcImag
// bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::COMPRESSED_SRGB));
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
if (image.hasAlphaChannel()) {
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::COMPRESSED_SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
}

View file

@ -32,6 +32,7 @@ void EngineStats::run(const SceneContextPointer& sceneContext, const RenderConte
config->textureGPUCount = gpu::Texture::getTextureGPUCount();
config->textureCPUMemoryUsage = gpu::Texture::getTextureCPUMemoryUsage();
config->textureGPUMemoryUsage = gpu::Texture::getTextureGPUMemoryUsage();
config->textureGPUVirtualMemoryUsage = gpu::Texture::getTextureGPUVirtualMemoryUsage();
gpu::ContextStats gpuStats(_gpuStats);
renderContext->args->_context->getStats(_gpuStats);
@ -45,6 +46,7 @@ void EngineStats::run(const SceneContextPointer& sceneContext, const RenderConte
config->frameTextureCount = _gpuStats._RSNumTextureBounded - gpuStats._RSNumTextureBounded;
config->frameTextureRate = config->frameTextureCount * frequency;
config->frameTextureMemoryUsage = _gpuStats._RSAmountTextureMemoryBounded - gpuStats._RSAmountTextureMemoryBounded;
config->emitDirty();
}

View file

@ -33,6 +33,7 @@ namespace render {
Q_PROPERTY(quint32 textureGPUCount MEMBER textureGPUCount NOTIFY dirty)
Q_PROPERTY(qint64 textureCPUMemoryUsage MEMBER textureCPUMemoryUsage NOTIFY dirty)
Q_PROPERTY(qint64 textureGPUMemoryUsage MEMBER textureGPUMemoryUsage NOTIFY dirty)
Q_PROPERTY(qint64 textureGPUVirtualMemoryUsage MEMBER textureGPUVirtualMemoryUsage NOTIFY dirty)
Q_PROPERTY(quint32 frameAPIDrawcallCount MEMBER frameAPIDrawcallCount NOTIFY dirty)
Q_PROPERTY(quint32 frameDrawcallCount MEMBER frameDrawcallCount NOTIFY dirty)
@ -43,7 +44,7 @@ namespace render {
Q_PROPERTY(quint32 frameTextureCount MEMBER frameTextureCount NOTIFY dirty)
Q_PROPERTY(quint32 frameTextureRate MEMBER frameTextureRate NOTIFY dirty)
Q_PROPERTY(quint32 frameTextureMemoryUsage MEMBER frameTextureMemoryUsage NOTIFY dirty)
public:
EngineStatsConfig() : Job::Config(true) {}
@ -57,6 +58,7 @@ namespace render {
quint32 textureGPUCount{ 0 };
qint64 textureCPUMemoryUsage{ 0 };
qint64 textureGPUMemoryUsage{ 0 };
qint64 textureGPUVirtualMemoryUsage{ 0 };
quint32 frameAPIDrawcallCount{ 0 };
quint32 frameDrawcallCount{ 0 };
@ -67,6 +69,7 @@ namespace render {
quint32 frameTextureCount{ 0 };
quint32 frameTextureRate{ 0 };
qint64 frameTextureMemoryUsage{ 0 };
void emitDirty() { emit dirty(); }