COmbining more intrumentation, mip generation on cpu and an improved blit for the derez case

This commit is contained in:
samcake 2017-02-03 12:03:59 -08:00
parent 6e3c58faf4
commit 27dab5c4ba
3 changed files with 49 additions and 20 deletions

View file

@ -113,6 +113,7 @@ void GLTextureTransferHelper::queueExecution(VoidLambda lambda) {
#define MAX_TRANSFERS_PER_PASS 2 #define MAX_TRANSFERS_PER_PASS 2
bool GLTextureTransferHelper::process() { bool GLTextureTransferHelper::process() {
PROFILE_RANGE(render_gpu_gl, __FUNCTION__)
// Take any new textures or commands off the queue // Take any new textures or commands off the queue
VoidLambdaList pendingCommands; VoidLambdaList pendingCommands;
TextureList newTransferTextures; TextureList newTransferTextures;
@ -151,6 +152,7 @@ bool GLTextureTransferHelper::process() {
#endif #endif
return true; return true;
} }
PROFILE_COUNTER_IF_CHANGED(render_gpu_gl, "transferringTextures", size_t, _transferringTextures.size())
static auto lastReport = usecTimestampNow(); static auto lastReport = usecTimestampNow();
auto now = usecTimestampNow(); auto now = usecTimestampNow();

View file

@ -297,6 +297,7 @@ void GL45Texture::startTransfer() {
} }
bool GL45Texture::continueTransfer() { bool GL45Texture::continueTransfer() {
PROFILE_RANGE(render_gpu_gl, "continueTransfer")
size_t maxFace = GL_TEXTURE_CUBE_MAP == _target ? CUBE_NUM_FACES : 1; size_t maxFace = GL_TEXTURE_CUBE_MAP == _target ? CUBE_NUM_FACES : 1;
for (uint8_t face = 0; face < maxFace; ++face) { for (uint8_t face = 0; face < maxFace; ++face) {
for (uint16_t mipLevel = _minMip; mipLevel <= _maxMip; ++mipLevel) { for (uint16_t mipLevel = _minMip; mipLevel <= _maxMip; ++mipLevel) {
@ -306,6 +307,8 @@ bool GL45Texture::continueTransfer() {
_sparseInfo.allocatedPages += _sparseInfo.getPageCount(size); _sparseInfo.allocatedPages += _sparseInfo.getPageCount(size);
} }
if (_gpuObject.isStoredMipFaceAvailable(mipLevel, face)) { if (_gpuObject.isStoredMipFaceAvailable(mipLevel, face)) {
PROFILE_RANGE_EX(render_gpu_gl, "texSubImage", 0x0000ffff, (size.x * size.y * maxFace / 1024));
auto mip = _gpuObject.accessStoredMipFace(mipLevel, face); auto mip = _gpuObject.accessStoredMipFace(mipLevel, face);
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat()); GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat());
if (GL_TEXTURE_2D == _target) { if (GL_TEXTURE_2D == _target) {
@ -379,6 +382,8 @@ void GL45Texture::stripToMip(uint16_t newMinMip) {
return; return;
} }
PROFILE_RANGE(render_gpu_gl, "GL45Texture::stripToMip");
auto mipLevels = usedMipLevels(); auto mipLevels = usedMipLevels();
{ {
Lock lock(texturesByMipCountsMutex); Lock lock(texturesByMipCountsMutex);
@ -420,29 +425,51 @@ void GL45Texture::stripToMip(uint16_t newMinMip) {
auto newLevels = usedMipLevels(); auto newLevels = usedMipLevels();
// Create and setup the new texture (allocate) // Create and setup the new texture (allocate)
glCreateTextures(_target, 1, &const_cast<GLuint&>(_id)); {
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0); Vec3u newDimensions = _gpuObject.evalMipDimensions(_mipOffset);
glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, _maxMip - _minMip); PROFILE_RANGE_EX(render_gpu_gl, "Re-Allocate", 0xff0000ff, (newDimensions.x * newDimensions.y));
Vec3u newDimensions = _gpuObject.evalMipDimensions(_mipOffset);
glTextureStorage2D(_id, newLevels, _internalFormat, newDimensions.x, newDimensions.y); glCreateTextures(_target, 1, &const_cast<GLuint&>(_id));
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0);
glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, _maxMip - _minMip);
glTextureStorage2D(_id, newLevels, _internalFormat, newDimensions.x, newDimensions.y);
}
// Copy the contents of the old texture to the new // Copy the contents of the old texture to the new
GLuint fbo { 0 }; {
glCreateFramebuffers(1, &fbo); PROFILE_RANGE(render_gpu_gl, "Blit");
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); /*
for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) { GLuint fbo { 0 };
uint16 sourceMip = targetMip + mipDelta; glCreateFramebuffers(1, &fbo);
Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset); glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
for (GLenum target : getFaceTargets(_target)) { for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) {
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, oldId, sourceMip); uint16 sourceMip = targetMip + mipDelta;
(void)CHECK_GL_ERROR(); Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset);
glCopyTextureSubImage2D(_id, targetMip, 0, 0, 0, 0, mipDimensions.x, mipDimensions.y); for (GLenum target : getFaceTargets(_target)) {
(void)CHECK_GL_ERROR(); glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, oldId, sourceMip);
(void)CHECK_GL_ERROR();
glCopyTextureSubImage2D(_id, targetMip, 0, 0, 0, 0, mipDimensions.x, mipDimensions.y);
(void)CHECK_GL_ERROR();
}
} }
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbo);
*/
for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) {
uint16 sourceMip = targetMip + mipDelta;
Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset);
for (GLenum target : getFaceTargets(_target)) {
glCopyImageSubData(
oldId, target, sourceMip, 0, 0, 0,
_id, target, targetMip, 0, 0, 0,
mipDimensions.x, mipDimensions.y, 1
);
(void)CHECK_GL_ERROR();
}
}
glDeleteTextures(1, &oldId);
} }
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbo);
glDeleteTextures(1, &oldId);
} }
// Re-sync the sampler to force access to the new mip level // Re-sync the sampler to force access to the new mip level

View file

@ -200,7 +200,7 @@ const QImage& image, bool isLinear, bool doCompress) {
} }
} }
#define CPU_MIPMAPS 0 #define CPU_MIPMAPS 1
void generateMips(gpu::Texture* texture, QImage& image, gpu::Element formatMip) { void generateMips(gpu::Texture* texture, QImage& image, gpu::Element formatMip) {
#if CPU_MIPMAPS #if CPU_MIPMAPS