mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
hopefully fixed zww issue with new efb to ram.
implemented new efb to ram in opengl modified TextureConversionShader preparing the implementation of new efb to ram in dx11 please test for regressions git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5874 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -52,6 +52,7 @@
|
||||
#include "FramebufferManager.h"
|
||||
#include "FileUtil.h"
|
||||
#include "HiresTextures.h"
|
||||
#include "TextureConverter.h"
|
||||
|
||||
u8 *TextureMngr::temp = NULL;
|
||||
TextureMngr::TexCache TextureMngr::textures;
|
||||
@ -95,13 +96,13 @@ bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int he
|
||||
return SaveTGA(filename, width, height, &data[0]);
|
||||
}
|
||||
|
||||
bool TextureMngr::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 range_size)
|
||||
int TextureMngr::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 range_size)
|
||||
{
|
||||
if (addr + size_in_bytes < range_address)
|
||||
return false;
|
||||
return -1;
|
||||
if (addr >= range_address + range_size)
|
||||
return false;
|
||||
return true;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode,TexMode1 &newmode1)
|
||||
@ -197,14 +198,8 @@ void TextureMngr::ProgressiveCleanup()
|
||||
{
|
||||
if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second.frameCount)
|
||||
{
|
||||
if (!iter->second.isRenderTarget) {
|
||||
iter->second.Destroy(false);
|
||||
textures.erase(iter++);
|
||||
}
|
||||
else {
|
||||
iter->second.Destroy(false);
|
||||
textures.erase(iter++);
|
||||
}
|
||||
iter->second.Destroy(false);
|
||||
iter = textures.erase(iter);
|
||||
}
|
||||
else
|
||||
++iter;
|
||||
@ -216,17 +211,34 @@ void TextureMngr::InvalidateRange(u32 start_address, u32 size)
|
||||
TexCache::iterator iter = textures.begin();
|
||||
while (iter != textures.end())
|
||||
{
|
||||
if (iter->second.IntersectsMemoryRange(start_address, size))
|
||||
int rangePosition = iter->second.IntersectsMemoryRange(start_address, size);
|
||||
if (rangePosition == 0)
|
||||
{
|
||||
iter->second.Destroy(false);
|
||||
textures.erase(iter++);
|
||||
}
|
||||
else {
|
||||
++iter;
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextureMngr::MakeRangeDynamic(u32 start_address, u32 size)
|
||||
{
|
||||
TexCache::iterator iter = textures.begin();
|
||||
while (iter != textures.end())
|
||||
{
|
||||
int rangePosition = iter->second.IntersectsMemoryRange(start_address, size);
|
||||
if ( rangePosition == 0)
|
||||
{
|
||||
iter->second.hash = 0;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width, int height, u32 tex_format, int tlutaddr, int tlutfmt)
|
||||
{
|
||||
// notes (about "UNsafe texture cache"):
|
||||
@ -273,6 +285,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||
u32 texID = address;
|
||||
u64 texHash = 0;
|
||||
u32 FullFormat = tex_format;
|
||||
bool TextureIsDinamic = false;
|
||||
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
||||
FullFormat = (tex_format | (tlutfmt << 16));
|
||||
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures)
|
||||
@ -306,19 +319,47 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||
TCacheEntry &entry = iter->second;
|
||||
|
||||
if (!g_ActiveConfig.bSafeTextureCache)
|
||||
hash_value = ((u32 *)ptr)[0];
|
||||
{
|
||||
if(entry.isRenderTarget || entry.isDinamic)
|
||||
{
|
||||
if(!g_ActiveConfig.bCopyEFBToTexture && g_ActiveConfig.bVerifyTextureModificationsByCPU)
|
||||
{
|
||||
hash_value = TexDecoder_GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
|
||||
{
|
||||
hash_value ^= TexDecoder_GetHash64(&texMem[tlutaddr], TexDecoder_GetPaletteSize(tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hash_value = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hash_value = ((u32 *)ptr)[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(entry.isRenderTarget || entry.isDinamic)
|
||||
{
|
||||
if(g_ActiveConfig.bCopyEFBToTexture || !g_ActiveConfig.bVerifyTextureModificationsByCPU)
|
||||
{
|
||||
hash_value = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entry.isRenderTarget || ((address == entry.addr) && (hash_value == entry.hash) && ((int) FullFormat == entry.fmt && entry.MipLevels >= maxlevel)))
|
||||
if (((entry.isRenderTarget || entry.isDinamic) && hash_value == entry.hash && address == entry.addr)
|
||||
|| ((address == entry.addr) && (hash_value == entry.hash) && ((int) FullFormat == entry.fmt) && entry.MipLevels >= maxlevel))
|
||||
{
|
||||
entry.frameCount = frameCount;
|
||||
glEnable(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D);
|
||||
// entry.isRectangle ? TextureMngr::EnableTex2D(texstage) : TextureMngr::EnableTexRECT(texstage);
|
||||
glBindTexture(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D, entry.texture);
|
||||
glBindTexture(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D, entry.texture);
|
||||
GL_REPORT_ERRORD();
|
||||
//if (entry.mode.hex != tm0.hex || entry.mode1.hex != tm1.hex)//gl needs this refreshed for every texture to work right
|
||||
entry.SetTextureParameters(tm0,tm1);
|
||||
//DebugLog("%cC addr: %08x | fmt: %i | e.hash: %08x | w:%04i h:%04i", g_ActiveConfig.bSafeTextureCache ? 'S' : 'U'
|
||||
// , address, tex_format, entry.hash, width, height);
|
||||
entry.SetTextureParameters(tm0,tm1);
|
||||
entry.isDinamic = false;
|
||||
return &entry;
|
||||
}
|
||||
else
|
||||
@ -326,12 +367,14 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||
// Let's reload the new texture data into the same texture,
|
||||
// instead of destroying it and having to create a new one.
|
||||
// Might speed up movie playback very, very slightly.
|
||||
if (width == entry.w && height == entry.h && (int) FullFormat == entry.fmt)
|
||||
{
|
||||
TextureIsDinamic = (entry.isRenderTarget || entry.isDinamic) && !g_ActiveConfig.bCopyEFBToTexture;
|
||||
if (!entry.isRenderTarget &&
|
||||
((!entry.isDinamic && width == entry.w && height==entry.h && FullFormat == entry.fmt)
|
||||
|| (entry.isDinamic && entry.w == width && entry.h == height)))
|
||||
{
|
||||
glBindTexture(entry.isRectangle ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D, entry.texture);
|
||||
GL_REPORT_ERRORD();
|
||||
//if (entry.mode.hex != tm0.hex || entry.mode1.hex != tm1.hex) //gl needs this refreshed for every texture to work right
|
||||
entry.SetTextureParameters(tm0,tm1);
|
||||
entry.SetTextureParameters(tm0,tm1);
|
||||
skip_texture_create = true;
|
||||
}
|
||||
else
|
||||
@ -344,6 +387,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||
|
||||
//Make an entry in the table
|
||||
TCacheEntry& entry = textures[texID];
|
||||
entry.isDinamic = TextureIsDinamic;
|
||||
PC_TexFormat dfmt = PC_TEX_FMT_NONE;
|
||||
|
||||
if (g_ActiveConfig.bHiresTextures)
|
||||
@ -370,12 +414,12 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
||||
|
||||
entry.oldpixel = ((u32 *)ptr)[0];
|
||||
|
||||
if (g_ActiveConfig.bSafeTextureCache)
|
||||
if (g_ActiveConfig.bSafeTextureCache || entry.isDinamic)
|
||||
entry.hash = hash_value;
|
||||
else
|
||||
else
|
||||
{
|
||||
entry.hash = (u32)(((double)rand() / RAND_MAX) * 0xFFFFFFFF);
|
||||
((u32 *)ptr)[0] = entry.hash;
|
||||
((u32 *)ptr)[0] = entry.hash;
|
||||
}
|
||||
|
||||
entry.addr = address;
|
||||
@ -575,9 +619,6 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
||||
// IA4,RA4 - IA4
|
||||
// Z8M,G8,I8,A8,Z8,R8,B8,Z8L - I8
|
||||
// Z16,GB8,RG8,Z16L,IA8,RA8 - IA8
|
||||
GLenum gl_format = GL_RGBA;
|
||||
GLenum gl_iformat = 4;
|
||||
GLenum gl_type = GL_UNSIGNED_BYTE;
|
||||
float colmat[16];
|
||||
float fConstAdd[4] = {0};
|
||||
memset(colmat, 0, sizeof(colmat));
|
||||
@ -688,6 +729,9 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
||||
int w = (abs(source_rect.GetWidth()) >> bScaleByHalf);
|
||||
int h = (abs(source_rect.GetHeight()) >> bScaleByHalf);
|
||||
|
||||
GLenum gl_format = GL_RGBA;
|
||||
GLenum gl_iformat = 4;
|
||||
GLenum gl_type = GL_UNSIGNED_BYTE;
|
||||
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
@ -699,12 +743,14 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
||||
GL_REPORT_ERRORD();
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, gl_iformat, w, h, 0, gl_format, gl_type, NULL);
|
||||
GL_REPORT_ERRORD();
|
||||
entry.isRenderTarget = true;
|
||||
entry.isDinamic = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_assert_(entry.texture);
|
||||
GL_REPORT_ERRORD();
|
||||
if (entry.w == w && entry.h == h && entry.isRectangle && entry.fmt == (int) copyfmt)
|
||||
if (entry.w == w && entry.h == h && entry.isRectangle)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
|
||||
// for some reason mario sunshine errors here...
|
||||
@ -717,6 +763,8 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, gl_iformat, w, h, 0, gl_format, gl_type, NULL);
|
||||
GL_REPORT_ERRORD();
|
||||
entry.isRenderTarget = true;
|
||||
entry.isDinamic = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -737,7 +785,6 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
||||
entry.w = w;
|
||||
entry.h = h;
|
||||
entry.isRectangle = true;
|
||||
entry.isRenderTarget = true;
|
||||
entry.fmt = copyfmt;
|
||||
|
||||
// Make sure to resolve anything we need to read from.
|
||||
@ -747,41 +794,57 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
|
||||
|
||||
// We have to run a pixel shader, for color conversion.
|
||||
Renderer::ResetAPIState(); // reset any game specific settings
|
||||
if(!entry.isDinamic || g_ActiveConfig.bCopyEFBToTexture)
|
||||
{
|
||||
if (s_TempFramebuffer == 0)
|
||||
glGenFramebuffersEXT(1, (GLuint *)&s_TempFramebuffer);
|
||||
|
||||
if (s_TempFramebuffer == 0)
|
||||
glGenFramebuffersEXT(1, (GLuint *)&s_TempFramebuffer);
|
||||
g_framebufferManager.SetFramebuffer(s_TempFramebuffer);
|
||||
// Bind texture to temporary framebuffer
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, entry.texture, 0);
|
||||
GL_REPORT_FBO_ERROR();
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture);
|
||||
|
||||
glViewport(0, 0, w, h);
|
||||
|
||||
g_framebufferManager.SetFramebuffer(s_TempFramebuffer);
|
||||
// Bind texture to temporary framebuffer
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, entry.texture, 0);
|
||||
GL_REPORT_FBO_ERROR();
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture);
|
||||
|
||||
glViewport(0, 0, w, h);
|
||||
PixelShaderCache::SetCurrentShader(bFromZBuffer ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram());
|
||||
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
PixelShaderCache::SetCurrentShader(bFromZBuffer ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram());
|
||||
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
||||
GL_REPORT_ERRORD();
|
||||
TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect);
|
||||
|
||||
TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1);
|
||||
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.top ); glVertex2f(-1, -1);
|
||||
glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.top ); glVertex2f( 1, -1);
|
||||
glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.bottom); glVertex2f( 1, 1);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1);
|
||||
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.top ); glVertex2f(-1, -1);
|
||||
glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.top ); glVertex2f( 1, -1);
|
||||
glTexCoord2f((GLfloat)targetSource.right, (GLfloat)targetSource.bottom); glVertex2f( 1, 1);
|
||||
glEnd();
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
// Unbind texture from temporary framebuffer
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
||||
// Unbind texture from temporary framebuffer
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
|
||||
}
|
||||
|
||||
if(!g_ActiveConfig.bCopyEFBToTexture)
|
||||
{
|
||||
textures[address].hash = TextureConverter::EncodeToRamFromTexture(
|
||||
address,
|
||||
read_texture,
|
||||
Renderer::GetTargetScaleX(),
|
||||
Renderer::GetTargetScaleY(),
|
||||
bFromZBuffer,
|
||||
bIsIntensityFmt,
|
||||
copyfmt,
|
||||
bScaleByHalf,
|
||||
source_rect);
|
||||
|
||||
}
|
||||
// Return to the EFB.
|
||||
g_framebufferManager.SetFramebuffer(0);
|
||||
Renderer::RestoreAPIState();
|
||||
|
Reference in New Issue
Block a user