mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Split the texture application into two stages.
The latter simply applies the texture. This makes our IsAlphaTestTriviallyTrue() check correct.
This commit is contained in:
parent
f107a2f3e5
commit
c7e6f051e4
5 changed files with 101 additions and 64 deletions
|
@ -51,7 +51,6 @@ void TextureCacheCommon::GetSamplingParams(int &minFilt, int &magFilt, bool &sCl
|
|||
minFilt |= 1;
|
||||
}
|
||||
if (g_Config.iTexFiltering == TEX_FILTER_LINEAR && (!gstate.isColorTestEnabled() || IsColorTestTriviallyTrue())) {
|
||||
// TODO: IsAlphaTestTriviallyTrue() is unsafe here. vertexFullAlpha is not calculated yet.
|
||||
if (!gstate.isAlphaTestEnabled() || IsAlphaTestTriviallyTrue()) {
|
||||
magFilt |= 1;
|
||||
minFilt |= 1;
|
||||
|
|
|
@ -747,6 +747,7 @@ void ShaderManager::DirtyLastShader() { // disables vertex arrays
|
|||
if (lastShader_)
|
||||
lastShader_->stop();
|
||||
lastShader_ = 0;
|
||||
lastVShaderSame_ = false;
|
||||
}
|
||||
|
||||
// This is to be used when debugging why incompatible shaders are being linked, like is
|
||||
|
|
|
@ -901,6 +901,8 @@ void TransformDrawEngine::ApplyDrawStateLate() {
|
|||
fragmentTestCache_->BindTestTexture(GL_TEXTURE2);
|
||||
}
|
||||
|
||||
textureCache_->ApplyTexture();
|
||||
|
||||
if (fboTexNeedBind_) {
|
||||
framebufferManager_->BindFramebufferColor(GL_TEXTURE1, gstate.getFrameBufRawAddress(), nullptr);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
|
|
|
@ -88,6 +88,8 @@ TextureCache::TextureCache() : cacheSizeEstimate_(0), secondCacheSizeEstimate_(0
|
|||
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyLevel);
|
||||
SetupTextureDecoder();
|
||||
|
||||
nextTexture_ = nullptr;
|
||||
}
|
||||
|
||||
TextureCache::~TextureCache() {
|
||||
|
@ -938,61 +940,7 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffe
|
|||
depal = depalShaderCache_->GetDepalettizeShader(clutFormat, framebuffer->drawnFormat);
|
||||
}
|
||||
if (depal) {
|
||||
GLuint clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_);
|
||||
FBO *depalFBO = framebufferManager_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, FBO_8888);
|
||||
fbo_bind_as_render_target(depalFBO);
|
||||
static const float pos[12] = {
|
||||
-1, -1, -1,
|
||||
1, -1, -1,
|
||||
1, 1, -1,
|
||||
-1, 1, -1
|
||||
};
|
||||
static const float uv[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
1, 1,
|
||||
0, 1,
|
||||
};
|
||||
static const GLubyte indices[4] = { 0, 1, 3, 2 };
|
||||
|
||||
shaderManager_->DirtyLastShader();
|
||||
|
||||
glUseProgram(depal->program);
|
||||
|
||||
glstate.arrayBuffer.unbind();
|
||||
glstate.elementArrayBuffer.unbind();
|
||||
glEnableVertexAttribArray(depal->a_position);
|
||||
glEnableVertexAttribArray(depal->a_texcoord0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, clutTexture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
framebufferManager_->BindFramebufferColor(GL_TEXTURE0, gstate.getFrameBufRawAddress(), framebuffer, true);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
#if !defined(USING_GLES2)
|
||||
glDisable(GL_LOGIC_OP);
|
||||
#endif
|
||||
glViewport(0, 0, framebuffer->renderWidth, framebuffer->renderHeight);
|
||||
|
||||
glVertexAttribPointer(depal->a_position, 3, GL_FLOAT, GL_FALSE, 12, pos);
|
||||
glVertexAttribPointer(depal->a_texcoord0, 2, GL_FLOAT, GL_FALSE, 8, uv);
|
||||
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, indices);
|
||||
glDisableVertexAttribArray(depal->a_position);
|
||||
glDisableVertexAttribArray(depal->a_texcoord0);
|
||||
|
||||
fbo_bind_color_as_texture(depalFBO, 0);
|
||||
glstate.Restore();
|
||||
framebufferManager_->RebindFramebuffer();
|
||||
|
||||
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
|
||||
const u32 bytesPerColor = clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16);
|
||||
const u32 clutTotalColors = clutMaxBytes_ / bytesPerColor;
|
||||
|
||||
|
@ -1001,7 +949,6 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffe
|
|||
gstate_c.textureSimpleAlpha = alphaStatus == TexCacheEntry::STATUS_ALPHA_SIMPLE;
|
||||
} else {
|
||||
entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE;
|
||||
framebufferManager_->BindFramebufferColor(GL_TEXTURE0, gstate.getFrameBufRawAddress(), framebuffer);
|
||||
|
||||
gstate_c.textureFullAlpha = gstate.getTextureFormat() == GE_TFMT_5650;
|
||||
gstate_c.textureSimpleAlpha = gstate_c.textureFullAlpha;
|
||||
|
@ -1020,7 +967,8 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffe
|
|||
if (gstate_c.curTextureXOffset != 0 || gstate_c.curTextureYOffset != 0) {
|
||||
gstate_c.needShaderTexClamp = true;
|
||||
}
|
||||
SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
|
||||
|
||||
nextTexture_ = entry;
|
||||
} else {
|
||||
if (framebuffer->fbo) {
|
||||
fbo_destroy(framebuffer->fbo);
|
||||
|
@ -1031,6 +979,92 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffe
|
|||
}
|
||||
}
|
||||
|
||||
void TextureCache::ApplyTexture() {
|
||||
if (nextTexture_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextTexture_->framebuffer) {
|
||||
ApplyTextureFramebuffer(nextTexture_, nextTexture_->framebuffer);
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, nextTexture_->textureName);
|
||||
lastBoundTexture = nextTexture_->textureName;
|
||||
UpdateSamplingParams(*nextTexture_, false);
|
||||
}
|
||||
|
||||
nextTexture_ = nullptr;
|
||||
}
|
||||
|
||||
void TextureCache::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) {
|
||||
DepalShader *depal = nullptr;
|
||||
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
|
||||
if ((entry->status & TexCacheEntry::STATUS_DEPALETTIZE) && !g_Config.bDisableSlowFramebufEffects) {
|
||||
depal = depalShaderCache_->GetDepalettizeShader(clutFormat, framebuffer->drawnFormat);
|
||||
}
|
||||
if (depal) {
|
||||
GLuint clutTexture = depalShaderCache_->GetClutTexture(clutFormat, clutHash_, clutBuf_);
|
||||
FBO *depalFBO = framebufferManager_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, FBO_8888);
|
||||
fbo_bind_as_render_target(depalFBO);
|
||||
static const float pos[12] = {
|
||||
-1, -1, -1,
|
||||
1, -1, -1,
|
||||
1, 1, -1,
|
||||
-1, 1, -1
|
||||
};
|
||||
static const float uv[8] = {
|
||||
0, 0,
|
||||
1, 0,
|
||||
1, 1,
|
||||
0, 1,
|
||||
};
|
||||
static const GLubyte indices[4] = { 0, 1, 3, 2 };
|
||||
|
||||
shaderManager_->DirtyLastShader();
|
||||
|
||||
glUseProgram(depal->program);
|
||||
|
||||
glstate.arrayBuffer.unbind();
|
||||
glstate.elementArrayBuffer.unbind();
|
||||
glEnableVertexAttribArray(depal->a_position);
|
||||
glEnableVertexAttribArray(depal->a_texcoord0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, clutTexture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
framebufferManager_->BindFramebufferColor(GL_TEXTURE0, gstate.getFrameBufRawAddress(), framebuffer, true);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
#if !defined(USING_GLES2)
|
||||
glDisable(GL_LOGIC_OP);
|
||||
#endif
|
||||
glViewport(0, 0, framebuffer->renderWidth, framebuffer->renderHeight);
|
||||
|
||||
glVertexAttribPointer(depal->a_position, 3, GL_FLOAT, GL_FALSE, 12, pos);
|
||||
glVertexAttribPointer(depal->a_texcoord0, 2, GL_FLOAT, GL_FALSE, 8, uv);
|
||||
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, indices);
|
||||
glDisableVertexAttribArray(depal->a_position);
|
||||
glDisableVertexAttribArray(depal->a_texcoord0);
|
||||
|
||||
fbo_bind_color_as_texture(depalFBO, 0);
|
||||
glstate.Restore();
|
||||
framebufferManager_->RebindFramebuffer();
|
||||
} else {
|
||||
framebufferManager_->BindFramebufferColor(GL_TEXTURE0, gstate.getFrameBufRawAddress(), framebuffer);
|
||||
}
|
||||
|
||||
SetFramebufferSamplingParams(framebuffer->bufferWidth, framebuffer->bufferHeight);
|
||||
|
||||
lastBoundTexture = -1;
|
||||
}
|
||||
|
||||
bool TextureCache::SetOffsetTexture(u32 offset) {
|
||||
if (g_Config.iRenderingMode != FB_BUFFERED_MODE) {
|
||||
return false;
|
||||
|
@ -1057,8 +1091,8 @@ bool TextureCache::SetOffsetTexture(u32 offset) {
|
|||
}
|
||||
|
||||
if (success && entry->framebuffer) {
|
||||
// This will not apply the texture immediately.
|
||||
SetTextureFramebuffer(entry, entry->framebuffer);
|
||||
lastBoundTexture = -1;
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
return true;
|
||||
}
|
||||
|
@ -1136,7 +1170,6 @@ void TextureCache::SetTexture(bool force) {
|
|||
if (entry->framebuffer) {
|
||||
if (match) {
|
||||
SetTextureFramebuffer(entry, entry->framebuffer);
|
||||
lastBoundTexture = -1;
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
return;
|
||||
} else {
|
||||
|
@ -1254,12 +1287,10 @@ void TextureCache::SetTexture(bool force) {
|
|||
//got one!
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
if (entry->textureName != lastBoundTexture) {
|
||||
glBindTexture(GL_TEXTURE_2D, entry->textureName);
|
||||
lastBoundTexture = entry->textureName;
|
||||
nextTexture_ = entry;
|
||||
gstate_c.textureFullAlpha = entry->GetAlphaStatus() == TexCacheEntry::STATUS_ALPHA_FULL;
|
||||
gstate_c.textureSimpleAlpha = entry->GetAlphaStatus() != TexCacheEntry::STATUS_ALPHA_UNKNOWN;
|
||||
}
|
||||
UpdateSamplingParams(*entry, false);
|
||||
VERBOSE_LOG(G3D, "Texture at %08x Found in Cache, applying", texaddr);
|
||||
return; //Done!
|
||||
} else {
|
||||
|
@ -1353,7 +1384,6 @@ void TextureCache::SetTexture(bool force) {
|
|||
// If we ended up with a framebuffer, attach it - no texture decoding needed.
|
||||
if (entry->framebuffer) {
|
||||
SetTextureFramebuffer(entry, entry->framebuffer);
|
||||
lastBoundTexture = -1;
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -92,6 +92,8 @@ public:
|
|||
|
||||
void SetFramebufferSamplingParams(u16 bufferWidth, u16 bufferHeight);
|
||||
|
||||
void ApplyTexture();
|
||||
|
||||
private:
|
||||
// Can't be unordered_map, we use lower_bound ... although for some reason that compiles on MSVC.
|
||||
typedef std::map<u64, TexCacheEntry> TexCache;
|
||||
|
@ -112,6 +114,7 @@ private:
|
|||
bool AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer, u32 texaddrOffset = 0);
|
||||
void DetachFramebuffer(TexCacheEntry *entry, u32 address, VirtualFramebuffer *framebuffer);
|
||||
void SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer);
|
||||
void ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer);
|
||||
|
||||
TexCache cache;
|
||||
TexCache secondCache;
|
||||
|
@ -150,6 +153,8 @@ private:
|
|||
bool clutAlphaLinear_;
|
||||
u16 clutAlphaLinearColor_;
|
||||
|
||||
TexCacheEntry *nextTexture_;
|
||||
|
||||
u32 lastBoundTexture;
|
||||
float maxAnisotropyLevel;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue