mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -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:
@ -81,10 +81,7 @@ void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const
|
||||
// bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
|
||||
if (!g_ActiveConfig.bEFBCopyDisable)
|
||||
{
|
||||
if (g_ActiveConfig.bCopyEFBToTexture) // To OGL Texture
|
||||
TextureMngr::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
||||
else // To RAM
|
||||
TextureConverter::EncodeToRam(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
||||
TextureMngr::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -886,9 +886,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
|
||||
// Copy the framebuffer to screen.
|
||||
|
||||
// Render to the real buffer now.
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer
|
||||
|
||||
|
||||
// Texture map s_xfbTexture onto the main buffer
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
||||
@ -905,6 +903,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
if(g_ActiveConfig.bUseXFB)
|
||||
{
|
||||
// draw each xfb source
|
||||
// Render to the real buffer now.
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer
|
||||
|
||||
for (u32 i = 0; i < xfbCount; ++i)
|
||||
{
|
||||
xfbSource = xfbSourceList[i];
|
||||
@ -992,6 +993,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
{
|
||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(Rc);
|
||||
GLuint read_texture = g_framebufferManager.ResolveAndGetRenderTarget(Rc);
|
||||
// Render to the real buffer now.
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture);
|
||||
if (applyShader)
|
||||
|
@ -112,7 +112,7 @@ FRAGMENTSHADER &GetOrCreateEncodingShader(u32 format)
|
||||
|
||||
if (s_encodingPrograms[format].glprogid == 0)
|
||||
{
|
||||
const char* shader = TextureConversionShader::GenerateEncodingShader(format);
|
||||
const char* shader = TextureConversionShader::GenerateEncodingShader(format,API_OPENGL);
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && shader) {
|
||||
@ -170,7 +170,7 @@ void Shutdown()
|
||||
void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const TargetRectangle& sourceRc,
|
||||
u8* destAddr, int dstWidth, int dstHeight, int readStride, bool toTexture, bool linearFilter)
|
||||
{
|
||||
Renderer::ResetAPIState();
|
||||
|
||||
|
||||
// switch to texture converter frame buffer
|
||||
// attach render buffer as color destination
|
||||
@ -240,13 +240,7 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar
|
||||
glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
g_framebufferManager.SetFramebuffer(0);
|
||||
VertexShaderManager::SetViewportChanged();
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||
TextureMngr::DisableStage(0);
|
||||
Renderer::RestoreAPIState();
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
}
|
||||
|
||||
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
|
||||
@ -312,6 +306,74 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
||||
scaledSource.right = expandedWidth / samples;
|
||||
|
||||
|
||||
int cacheBytes = 32;
|
||||
if ((format & 0x0f) == 6)
|
||||
cacheBytes = 64;
|
||||
|
||||
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
||||
Renderer::ResetAPIState();
|
||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0);
|
||||
g_framebufferManager.SetFramebuffer(0);
|
||||
VertexShaderManager::SetViewportChanged();
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||
TextureMngr::DisableStage(0);
|
||||
Renderer::RestoreAPIState();
|
||||
GL_REPORT_ERRORD();
|
||||
}
|
||||
|
||||
|
||||
u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY,bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
|
||||
{
|
||||
u32 format = copyfmt;
|
||||
|
||||
if (bFromZBuffer)
|
||||
{
|
||||
format |= _GX_TF_ZTF;
|
||||
if (copyfmt == 11)
|
||||
format = GX_TF_Z16;
|
||||
else if (format < GX_TF_Z8 || format > GX_TF_Z24X8)
|
||||
format |= _GX_TF_CTF;
|
||||
}
|
||||
else
|
||||
if (copyfmt > GX_TF_RGBA8 || (copyfmt < GX_TF_RGB565 && !bIsIntensityFmt))
|
||||
format |= _GX_TF_CTF;
|
||||
|
||||
FRAGMENTSHADER& texconv_shader = GetOrCreateEncodingShader(format);
|
||||
if (texconv_shader.glprogid == 0)
|
||||
return 0;
|
||||
|
||||
u8 *dest_ptr = Memory_GetPtr(address);
|
||||
|
||||
int width = (source.right - source.left) >> bScaleByHalf;
|
||||
int height = (source.bottom - source.top) >> bScaleByHalf;
|
||||
|
||||
int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format);
|
||||
|
||||
u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
|
||||
u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
|
||||
u16 samples = TextureConversionShader::GetEncodedSampleCount(format);
|
||||
|
||||
// only copy on cache line boundaries
|
||||
// extra pixels are copied but not displayed in the resulting texture
|
||||
s32 expandedWidth = (width + blkW) & (~blkW);
|
||||
s32 expandedHeight = (height + blkH) & (~blkH);
|
||||
|
||||
float sampleStride = bScaleByHalf?2.0f:1.0f;
|
||||
float top = (EFB_HEIGHT - source.top - expandedHeight) * MValueY ;
|
||||
TextureConversionShader::SetShaderParameters((float)expandedWidth,
|
||||
expandedHeight * MValueY,
|
||||
source.left * MValueX,
|
||||
top,
|
||||
sampleStride * MValueX,
|
||||
sampleStride * MValueY);
|
||||
|
||||
TargetRectangle scaledSource;
|
||||
scaledSource.top = 0;
|
||||
scaledSource.bottom = expandedHeight;
|
||||
scaledSource.left = 0;
|
||||
scaledSource.right = expandedWidth / samples;
|
||||
|
||||
|
||||
int cacheBytes = 32;
|
||||
if ((format & 0x0f) == 6)
|
||||
cacheBytes = 64;
|
||||
@ -319,12 +381,26 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
||||
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
||||
|
||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0);
|
||||
TextureMngr::MakeRangeDynamic(address,size_in_bytes);
|
||||
u64 Hashvalue = 0;
|
||||
if(g_ActiveConfig.bVerifyTextureModificationsByCPU)
|
||||
{
|
||||
Hashvalue = TexDecoder_GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||
}
|
||||
return Hashvalue;
|
||||
}
|
||||
|
||||
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
|
||||
u8* destAddr, int dstWidth, int dstHeight)
|
||||
{
|
||||
Renderer::ResetAPIState();
|
||||
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
||||
g_framebufferManager.SetFramebuffer(0);
|
||||
VertexShaderManager::SetViewportChanged();
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||
TextureMngr::DisableStage(0);
|
||||
Renderer::RestoreAPIState();
|
||||
GL_REPORT_ERRORD();
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,6 +37,8 @@ void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
|
||||
|
||||
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture);
|
||||
|
||||
u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
|
||||
|
||||
}
|
||||
|
||||
#endif // _TEXTURECONVERTER_H_
|
||||
|
@ -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();
|
||||
|
@ -29,7 +29,7 @@ class TextureMngr
|
||||
public:
|
||||
struct TCacheEntry
|
||||
{
|
||||
TCacheEntry() : texture(0), addr(0), size_in_bytes(0), hash(0), w(0), h(0),MipLevels(0), scaleX(1.0f), scaleY(1.0f), isRenderTarget(false), isRectangle(true), bHaveMipMaps(false) { mode.hex = 0xFCFCFCFC; }
|
||||
TCacheEntry() : texture(0), addr(0), size_in_bytes(0), hash(0), w(0), h(0),MipLevels(0), scaleX(1.0f), scaleY(1.0f),isDinamic(false), isRenderTarget(false), isRectangle(true), bHaveMipMaps(false) { mode.hex = 0xFCFCFCFC; }
|
||||
|
||||
GLuint texture;
|
||||
u32 addr;
|
||||
@ -47,13 +47,14 @@ public:
|
||||
|
||||
bool isRenderTarget; // if render texture, then rendertex is filled with the direct copy of the render target
|
||||
// later conversions would have to convert properly from rendertexfmt to texfmt
|
||||
bool isDinamic;// mofified from cpu
|
||||
bool isRectangle; // if nonpow2, use GL_TEXTURE_2D, else GL_TEXTURE_RECTANGLE_NV
|
||||
bool bHaveMipMaps;
|
||||
|
||||
void SetTextureParameters(TexMode0& newmode,TexMode1 &newmode1);
|
||||
void Destroy(bool shutdown);
|
||||
void ConvertFromRenderTarget(u32 taddr, int twidth, int theight, int tformat, int tlutaddr, int tlutfmt);
|
||||
bool IntersectsMemoryRange(u32 range_address, u32 range_size);
|
||||
int IntersectsMemoryRange(u32 range_address, u32 range_size);
|
||||
};
|
||||
|
||||
private:
|
||||
@ -68,7 +69,7 @@ public:
|
||||
static void Shutdown();
|
||||
static void Invalidate(bool shutdown);
|
||||
static void InvalidateRange(u32 start_address, u32 size);
|
||||
|
||||
static void MakeRangeDynamic(u32 start_address, u32 size);
|
||||
static TCacheEntry* Load(int texstage, u32 address, int width, int height, u32 format, int tlutaddr, int tlutfmt);
|
||||
static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source);
|
||||
|
||||
|
Reference in New Issue
Block a user