diff --git a/GPU/GLES/TextureCacheGLES.cpp b/GPU/GLES/TextureCacheGLES.cpp index b6cd1cc038..e7bd03f2d5 100644 --- a/GPU/GLES/TextureCacheGLES.cpp +++ b/GPU/GLES/TextureCacheGLES.cpp @@ -689,6 +689,8 @@ void TextureCacheGLES::BuildTexture(TexCacheEntry *const entry, bool replaceImag entry->SetAlphaStatus(TexCacheEntry::TexStatus(replaced.AlphaStatus())); } + render_->FinalizeTexture(entry->textureName, texMaxLevel); + // This will rebind it, but that's okay. // Need to actually bind it now - it might only have gotten bound in the init phase. render_->BindTexture(0, entry->textureName); diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index dbfa828426..d7870682d0 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -176,17 +176,27 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps) { { GLRTexture *tex = step.texture_image.texture; CHECK_GL_ERROR_IF_DEBUG(); - if (boundTexture != step.texture_image.texture->texture) { - glBindTexture(step.texture_image.texture->target, step.texture_image.texture->texture); - boundTexture = step.texture_image.texture->texture; + if (boundTexture != tex->texture) { + glBindTexture(tex->target, tex->texture); + boundTexture = tex->texture; } glTexImage2D(tex->target, step.texture_image.level, step.texture_image.internalFormat, step.texture_image.width, step.texture_image.height, 0, step.texture_image.format, step.texture_image.type, step.texture_image.data); delete[] step.texture_image.data; CHECK_GL_ERROR_IF_DEBUG(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, step.texture_image.linearFilter ? GL_LINEAR : GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, step.texture_image.linearFilter ? GL_LINEAR : GL_NEAREST); + glTexParameteri(step.texture_finalize.texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(step.texture_finalize.texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(step.texture_finalize.texture->target, GL_TEXTURE_MAG_FILTER, step.texture_image.linearFilter ? GL_LINEAR : GL_NEAREST); + glTexParameteri(step.texture_finalize.texture->target, GL_TEXTURE_MIN_FILTER, step.texture_image.linearFilter ? GL_LINEAR : GL_NEAREST); + break; + } + case GLRInitStepType::TEXTURE_FINALIZE: + { + GLRTexture *tex = step.texture_finalize.texture; + if (boundTexture != tex->texture) { + glBindTexture(tex->target, tex->texture); + boundTexture = tex->texture; + } + glTexParameteri(step.texture_finalize.texture->target, GL_TEXTURE_MAX_LEVEL, step.texture_finalize.maxLevel); break; } default: diff --git a/ext/native/thin3d/GLQueueRunner.h b/ext/native/thin3d/GLQueueRunner.h index e4c221b8e1..d155dbe9be 100644 --- a/ext/native/thin3d/GLQueueRunner.h +++ b/ext/native/thin3d/GLQueueRunner.h @@ -178,6 +178,7 @@ enum class GLRInitStepType : uint8_t { TEXTURE_IMAGE, TEXTURE_SUBDATA, + TEXTURE_FINALIZE, BUFFER_SUBDATA, }; @@ -229,6 +230,10 @@ struct GLRInitStep { bool linearFilter; uint8_t *data; // owned, delete[]-d } texture_image; + struct { + GLRTexture *texture; + int maxLevel; + } texture_finalize; }; }; diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index c7dcc0b805..04d5d165a8 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -317,6 +317,13 @@ public: initSteps_.push_back(step); } + void FinalizeTexture(GLRTexture *texture, int maxLevels) { + GLRInitStep step{ GLRInitStepType::TEXTURE_FINALIZE }; + step.texture_finalize.texture = texture; + step.texture_finalize.maxLevel = maxLevels; + initSteps_.push_back(step); + } + void BindTexture(int slot, GLRTexture *tex) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::BINDTEXTURE };