mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-11 15:13:37 +02:00
Merge pull request #5150 from unknownbrackets/texcache
Duplicate framebuffers that are rendered onto themselves
This commit is contained in:
@@ -740,8 +740,10 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) {
|
||||
|
||||
case GE_CMD_REGION1:
|
||||
case GE_CMD_REGION2:
|
||||
if (diff)
|
||||
if (diff) {
|
||||
gstate_c.framebufChanged = true;
|
||||
gstate_c.textureChanged = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_CMD_CLIPENABLE:
|
||||
@@ -830,8 +832,10 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) {
|
||||
case GE_CMD_FRAMEBUFPTR:
|
||||
case GE_CMD_FRAMEBUFWIDTH:
|
||||
case GE_CMD_FRAMEBUFPIXFORMAT:
|
||||
if (diff)
|
||||
if (diff) {
|
||||
gstate_c.framebufChanged = true;
|
||||
gstate_c.textureChanged = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXADDR0:
|
||||
@@ -1045,8 +1049,10 @@ void DIRECTX9_GPU::ExecuteOp(u32 op, u32 diff) {
|
||||
case GE_CMD_VIEWPORTY2:
|
||||
case GE_CMD_VIEWPORTZ1:
|
||||
case GE_CMD_VIEWPORTZ2:
|
||||
if (diff)
|
||||
if (diff) {
|
||||
gstate_c.framebufChanged = true;
|
||||
gstate_c.textureChanged = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_CMD_LIGHTENABLE0:
|
||||
|
||||
@@ -331,6 +331,10 @@ FramebufferManager::~FramebufferManager() {
|
||||
}
|
||||
SetNumExtraFBOs(0);
|
||||
|
||||
for (auto it = renderCopies_.begin(), end = renderCopies_.end(); it != end; ++it) {
|
||||
fbo_destroy(it->second);
|
||||
}
|
||||
|
||||
#ifndef USING_GLES2
|
||||
delete [] pixelBufObj_;
|
||||
#endif
|
||||
@@ -907,6 +911,7 @@ void FramebufferManager::BindFramebufferDepth(VirtualFramebuffer *sourceframebuf
|
||||
if (MaskedEqual(sourceframebuffer->z_address, targetframebuffer->z_address) &&
|
||||
sourceframebuffer->renderWidth == targetframebuffer->renderWidth &&
|
||||
sourceframebuffer->renderHeight == targetframebuffer->renderHeight) {
|
||||
|
||||
#ifndef USING_GLES2
|
||||
if (gl_extensions.FBO_ARB) {
|
||||
#else
|
||||
@@ -922,7 +927,53 @@ void FramebufferManager::BindFramebufferDepth(VirtualFramebuffer *sourceframebuf
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManager::BindFramebufferColor(VirtualFramebuffer *framebuffer) {
|
||||
if (!framebuffer->fbo || !useBufferedRendering_) {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (MaskedEqual(framebuffer->fb_address, gstate.getFrameBufRawAddress())) {
|
||||
#ifndef USING_GLES2
|
||||
if (gl_extensions.FBO_ARB) {
|
||||
#else
|
||||
if (gl_extensions.GLES3) {
|
||||
#endif
|
||||
#ifdef MAY_HAVE_GLES3
|
||||
|
||||
// TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size.
|
||||
FBO *renderCopy = NULL;
|
||||
std::pair<int, int> copySize = std::make_pair((int)framebuffer->renderWidth, (int)framebuffer->renderHeight);
|
||||
for (auto it = renderCopies_.begin(), end = renderCopies_.end(); it != end; ++it) {
|
||||
if (it->first == copySize) {
|
||||
renderCopy = it->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!renderCopy) {
|
||||
renderCopy = fbo_create(framebuffer->renderWidth, framebuffer->renderHeight, 1, true, framebuffer->colorDepth);
|
||||
renderCopies_[copySize] = renderCopy;
|
||||
}
|
||||
|
||||
fbo_bind_as_render_target(renderCopy);
|
||||
glViewport(0, 0, framebuffer->renderWidth, framebuffer->renderHeight);
|
||||
fbo_bind_for_read(framebuffer->fbo);
|
||||
glBlitFramebuffer(0, 0, framebuffer->renderWidth, framebuffer->renderHeight, 0, 0, framebuffer->renderWidth, framebuffer->renderHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
|
||||
fbo_bind_as_render_target(currentRenderVfb_->fbo);
|
||||
if (gl_extensions.gpuVendor != GPU_VENDOR_POWERVR)
|
||||
glstate.viewport.restore();
|
||||
fbo_bind_color_as_texture(renderCopy, 0);
|
||||
#endif
|
||||
} else {
|
||||
fbo_bind_color_as_texture(framebuffer->fbo, 0);
|
||||
}
|
||||
} else {
|
||||
fbo_bind_color_as_texture(framebuffer->fbo, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferManager::CopyDisplayToOutput() {
|
||||
|
||||
@@ -139,7 +139,10 @@ public:
|
||||
void SetLineWidth();
|
||||
|
||||
void BindFramebufferDepth(VirtualFramebuffer *sourceframebuffer, VirtualFramebuffer *targetframebuffer);
|
||||
|
||||
|
||||
// For use when texturing from a framebuffer. May create a duplicate if target.
|
||||
void BindFramebufferColor(VirtualFramebuffer *framebuffer);
|
||||
|
||||
// Just for logging right now. Might remove/change.
|
||||
void NotifyBlockTransfer(u32 dst, u32 src);
|
||||
|
||||
@@ -228,6 +231,7 @@ private:
|
||||
bool useBufferedRendering_;
|
||||
|
||||
std::vector<VirtualFramebuffer *> bvfbs_; // blitting FBOs
|
||||
std::map<std::pair<int, int>, FBO *> renderCopies_;
|
||||
|
||||
std::set<std::pair<u32, u32>> knownFramebufferCopies_;
|
||||
|
||||
|
||||
+13
-4
@@ -397,6 +397,7 @@ GLES_GPU::GLES_GPU()
|
||||
transformDraw_.SetFramebufferManager(&framebufferManager_);
|
||||
framebufferManager_.SetTextureCache(&textureCache_);
|
||||
framebufferManager_.SetShaderManager(shaderManager_);
|
||||
textureCache_.SetFramebufferManager(&framebufferManager_);
|
||||
|
||||
// Sanity check gstate
|
||||
if ((int *)&gstate.transferstart - (int *)&gstate != 0xEA) {
|
||||
@@ -893,8 +894,10 @@ void GLES_GPU::ExecuteOpInternal(u32 op, u32 diff) {
|
||||
|
||||
case GE_CMD_REGION1:
|
||||
case GE_CMD_REGION2:
|
||||
if (diff)
|
||||
if (diff) {
|
||||
gstate_c.framebufChanged = true;
|
||||
gstate_c.textureChanged = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_CMD_CLIPENABLE:
|
||||
@@ -970,8 +973,10 @@ void GLES_GPU::ExecuteOpInternal(u32 op, u32 diff) {
|
||||
|
||||
case GE_CMD_SCISSOR1:
|
||||
case GE_CMD_SCISSOR2:
|
||||
if (diff)
|
||||
if (diff) {
|
||||
gstate_c.framebufChanged = true;
|
||||
gstate_c.textureChanged = true;
|
||||
}
|
||||
break;
|
||||
|
||||
///
|
||||
@@ -982,8 +987,10 @@ void GLES_GPU::ExecuteOpInternal(u32 op, u32 diff) {
|
||||
case GE_CMD_FRAMEBUFPTR:
|
||||
case GE_CMD_FRAMEBUFWIDTH:
|
||||
case GE_CMD_FRAMEBUFPIXFORMAT:
|
||||
if (diff)
|
||||
if (diff) {
|
||||
gstate_c.framebufChanged = true;
|
||||
gstate_c.textureChanged = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXADDR0:
|
||||
@@ -1209,8 +1216,10 @@ void GLES_GPU::ExecuteOpInternal(u32 op, u32 diff) {
|
||||
case GE_CMD_VIEWPORTY2:
|
||||
case GE_CMD_VIEWPORTZ1:
|
||||
case GE_CMD_VIEWPORTZ2:
|
||||
if (diff)
|
||||
if (diff) {
|
||||
gstate_c.framebufChanged = true;
|
||||
gstate_c.textureChanged = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_CMD_LIGHTENABLE0:
|
||||
|
||||
+36
-48
@@ -285,7 +285,7 @@ void TextureCache::NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffe
|
||||
}
|
||||
}
|
||||
|
||||
void *TextureCache::UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u32 level) {
|
||||
void *TextureCache::UnswizzleFromMem(const u8 *texptr, u32 bufw, u32 bytesPerPixel, u32 level) {
|
||||
const u32 rowWidth = (bytesPerPixel > 0) ? (bufw * bytesPerPixel) : (bufw / 2);
|
||||
const u32 pitch = rowWidth / 4;
|
||||
const int bxc = rowWidth / 16;
|
||||
@@ -295,7 +295,7 @@ void *TextureCache::UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u
|
||||
|
||||
u32 ydest = 0;
|
||||
if (rowWidth >= 16) {
|
||||
const u32 *src = (u32 *) Memory::GetPointer(texaddr);
|
||||
const u32 *src = (const u32 *) texptr;
|
||||
u32 *ydestp = tmpTexBuf32.data();
|
||||
for (int by = 0; by < byc; by++) {
|
||||
u32 *xdest = ydestp;
|
||||
@@ -311,7 +311,7 @@ void *TextureCache::UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u
|
||||
ydestp += (rowWidth * 8) / 4;
|
||||
}
|
||||
} else if (rowWidth == 8) {
|
||||
const u32 *src = (u32 *) Memory::GetPointer(texaddr);
|
||||
const u32 *src = (const u32 *) texptr;
|
||||
for (int by = 0; by < byc; by++) {
|
||||
for (int n = 0; n < 8; n++, ydest += 2) {
|
||||
tmpTexBuf32[ydest + 0] = *src++;
|
||||
@@ -320,7 +320,7 @@ void *TextureCache::UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u
|
||||
}
|
||||
}
|
||||
} else if (rowWidth == 4) {
|
||||
const u32 *src = (u32 *) Memory::GetPointer(texaddr);
|
||||
const u32 *src = (const u32 *) texptr;
|
||||
for (int by = 0; by < byc; by++) {
|
||||
for (int n = 0; n < 8; n++, ydest++) {
|
||||
tmpTexBuf32[ydest] = *src++;
|
||||
@@ -328,7 +328,7 @@ void *TextureCache::UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u
|
||||
}
|
||||
}
|
||||
} else if (rowWidth == 2) {
|
||||
const u16 *src = (u16 *) Memory::GetPointer(texaddr);
|
||||
const u16 *src = (const u16 *) texptr;
|
||||
for (int by = 0; by < byc; by++) {
|
||||
for (int n = 0; n < 4; n++, ydest++) {
|
||||
u16 n1 = src[0];
|
||||
@@ -338,7 +338,7 @@ void *TextureCache::UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u
|
||||
}
|
||||
}
|
||||
} else if (rowWidth == 1) {
|
||||
const u8 *src = (u8 *) Memory::GetPointer(texaddr);
|
||||
const u8 *src = (const u8 *) texptr;
|
||||
for (int by = 0; by < byc; by++) {
|
||||
for (int n = 0; n < 2; n++, ydest++) {
|
||||
u8 n1 = src[ 0];
|
||||
@@ -353,7 +353,7 @@ void *TextureCache::UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u
|
||||
return tmpTexBuf32.data();
|
||||
}
|
||||
|
||||
void *TextureCache::ReadIndexedTex(int level, u32 texaddr, int bytesPerIndex, GLuint dstFmt, int bufw) {
|
||||
void *TextureCache::ReadIndexedTex(int level, const u8 *texptr, int bytesPerIndex, GLuint dstFmt, int bufw) {
|
||||
int w = gstate.getTextureWidth(level);
|
||||
int h = gstate.getTextureHeight(level);
|
||||
int length = bufw * h;
|
||||
@@ -369,20 +369,20 @@ void *TextureCache::ReadIndexedTex(int level, u32 texaddr, int bytesPerIndex, GL
|
||||
if (!gstate.isTextureSwizzled()) {
|
||||
switch (bytesPerIndex) {
|
||||
case 1:
|
||||
DeIndexTexture<u8>(tmpTexBuf16.data(), texaddr, length, clut);
|
||||
DeIndexTexture(tmpTexBuf16.data(), (const u8 *)texptr, length, clut);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
DeIndexTexture<u16_le>(tmpTexBuf16.data(), texaddr, length, clut);
|
||||
DeIndexTexture(tmpTexBuf16.data(), (const u16_le *)texptr, length, clut);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
DeIndexTexture<u32_le>(tmpTexBuf16.data(), texaddr, length, clut);
|
||||
DeIndexTexture(tmpTexBuf16.data(), (const u32_le *)texptr, length, clut);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
tmpTexBuf32.resize(std::max(bufw, w) * h);
|
||||
UnswizzleFromMem(texaddr, bufw, bytesPerIndex, level);
|
||||
UnswizzleFromMem(texptr, bufw, bytesPerIndex, level);
|
||||
switch (bytesPerIndex) {
|
||||
case 1:
|
||||
DeIndexTexture(tmpTexBuf16.data(), (u8 *) tmpTexBuf32.data(), length, clut);
|
||||
@@ -409,20 +409,20 @@ void *TextureCache::ReadIndexedTex(int level, u32 texaddr, int bytesPerIndex, GL
|
||||
if (!gstate.isTextureSwizzled()) {
|
||||
switch (bytesPerIndex) {
|
||||
case 1:
|
||||
DeIndexTexture<u8>(tmpTexBuf32.data(), texaddr, length, clut);
|
||||
DeIndexTexture(tmpTexBuf32.data(), (const u8 *)texptr, length, clut);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
DeIndexTexture<u16_le>(tmpTexBuf32.data(), texaddr, length, clut);
|
||||
DeIndexTexture(tmpTexBuf32.data(), (const u16_le *)texptr, length, clut);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
DeIndexTexture<u32_le>(tmpTexBuf32.data(), texaddr, length, clut);
|
||||
DeIndexTexture(tmpTexBuf32.data(), (const u32_le *)texptr, length, clut);
|
||||
break;
|
||||
}
|
||||
buf = tmpTexBuf32.data();
|
||||
} else {
|
||||
UnswizzleFromMem(texaddr, bufw, bytesPerIndex, level);
|
||||
UnswizzleFromMem(texptr, bufw, bytesPerIndex, level);
|
||||
// Since we had to unswizzle to tmpTexBuf32, let's output to tmpTexBuf16.
|
||||
tmpTexBuf16.resize(std::max(bufw, w) * h * 2);
|
||||
u32 *dest32 = (u32 *) tmpTexBuf16.data();
|
||||
@@ -830,22 +830,15 @@ bool SetDebugTexture() {
|
||||
}
|
||||
#endif
|
||||
|
||||
void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry)
|
||||
{
|
||||
void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry) {
|
||||
entry->framebuffer->usageFlags |= FB_USAGE_TEXTURE;
|
||||
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
|
||||
if (useBufferedRendering) {
|
||||
// For now, let's not bind FBOs that we know are off (invalidHint will be -1.)
|
||||
// But let's still not use random memory.
|
||||
if (entry->framebuffer->fbo) {
|
||||
fbo_bind_color_as_texture(entry->framebuffer->fbo, 0);
|
||||
// Keep the framebuffer alive.
|
||||
// TODO: Dangerous if it sets a new one?
|
||||
entry->framebuffer->last_frame_used = gpuStats.numFlips;
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE;
|
||||
}
|
||||
framebufferManager_->BindFramebufferColor(entry->framebuffer);
|
||||
|
||||
// Keep the framebuffer alive.
|
||||
entry->framebuffer->last_frame_used = gpuStats.numFlips;
|
||||
|
||||
// We need to force it, since we may have set it on a texture before attaching.
|
||||
UpdateSamplingParams(*entry, true);
|
||||
gstate_c.curTextureWidth = entry->framebuffer->width;
|
||||
@@ -883,11 +876,6 @@ void TextureCache::SetTexture(bool force) {
|
||||
int w = gstate.getTextureWidth(0);
|
||||
int h = gstate.getTextureHeight(0);
|
||||
|
||||
u32 fb_addr = gstate.getFrameBufRawAddress() | 0x04000000;
|
||||
if (fb_addr == gstate.getTextureAddress(0)) {
|
||||
WARN_LOG_REPORT(HLE, "Texturing from same buffer as target (%08x : %ix%i)", fb_addr, w, h);
|
||||
}
|
||||
|
||||
GETextureFormat format = gstate.getTextureFormat();
|
||||
if (format >= 11) {
|
||||
ERROR_LOG_REPORT(G3D, "Unknown texture format %i", format);
|
||||
@@ -1263,17 +1251,17 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
|
||||
texByteAlign = 2;
|
||||
if (!gstate.isTextureSwizzled()) {
|
||||
if (clutAlphaLinear_ && mipmapShareClut) {
|
||||
DeIndexTexture4Optimal(tmpTexBuf16.data(), texaddr, bufw * h, clutAlphaLinearColor_);
|
||||
DeIndexTexture4Optimal(tmpTexBuf16.data(), texptr, bufw * h, clutAlphaLinearColor_);
|
||||
} else {
|
||||
DeIndexTexture4(tmpTexBuf16.data(), texaddr, bufw * h, clut);
|
||||
DeIndexTexture4(tmpTexBuf16.data(), texptr, bufw * h, clut);
|
||||
}
|
||||
} else {
|
||||
tmpTexBuf32.resize(std::max(bufw, w) * h);
|
||||
UnswizzleFromMem(texaddr, bufw, 0, level);
|
||||
UnswizzleFromMem(texptr, bufw, 0, level);
|
||||
if (clutAlphaLinear_ && mipmapShareClut) {
|
||||
DeIndexTexture4Optimal(tmpTexBuf16.data(), (u8 *)tmpTexBuf32.data(), bufw * h, clutAlphaLinearColor_);
|
||||
DeIndexTexture4Optimal(tmpTexBuf16.data(), (const u8 *)tmpTexBuf32.data(), bufw * h, clutAlphaLinearColor_);
|
||||
} else {
|
||||
DeIndexTexture4(tmpTexBuf16.data(), (u8 *)tmpTexBuf32.data(), bufw * h, clut);
|
||||
DeIndexTexture4(tmpTexBuf16.data(), (const u8 *)tmpTexBuf32.data(), bufw * h, clut);
|
||||
}
|
||||
}
|
||||
finalBuf = tmpTexBuf16.data();
|
||||
@@ -1286,10 +1274,10 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
|
||||
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
|
||||
const u32 *clut = GetCurrentClut<u32>() + clutSharingOffset;
|
||||
if (!gstate.isTextureSwizzled()) {
|
||||
DeIndexTexture4(tmpTexBuf32.data(), texaddr, bufw * h, clut);
|
||||
DeIndexTexture4(tmpTexBuf32.data(), texptr, bufw * h, clut);
|
||||
finalBuf = tmpTexBuf32.data();
|
||||
} else {
|
||||
UnswizzleFromMem(texaddr, bufw, 0, level);
|
||||
UnswizzleFromMem(texptr, bufw, 0, level);
|
||||
// Let's reuse tmpTexBuf16, just need double the space.
|
||||
tmpTexBuf16.resize(std::max(bufw, w) * h * 2);
|
||||
DeIndexTexture4((u32 *)tmpTexBuf16.data(), (u8 *)tmpTexBuf32.data(), bufw * h, clut);
|
||||
@@ -1307,17 +1295,17 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
|
||||
|
||||
case GE_TFMT_CLUT8:
|
||||
texByteAlign = texByteAlignMap[gstate.getClutPaletteFormat()];
|
||||
finalBuf = ReadIndexedTex(level, texaddr, 1, dstFmt, bufw);
|
||||
finalBuf = ReadIndexedTex(level, texptr, 1, dstFmt, bufw);
|
||||
break;
|
||||
|
||||
case GE_TFMT_CLUT16:
|
||||
texByteAlign = texByteAlignMap[gstate.getClutPaletteFormat()];
|
||||
finalBuf = ReadIndexedTex(level, texaddr, 2, dstFmt, bufw);
|
||||
finalBuf = ReadIndexedTex(level, texptr, 2, dstFmt, bufw);
|
||||
break;
|
||||
|
||||
case GE_TFMT_CLUT32:
|
||||
texByteAlign = texByteAlignMap[gstate.getClutPaletteFormat()];
|
||||
finalBuf = ReadIndexedTex(level, texaddr, 4, dstFmt, bufw);
|
||||
finalBuf = ReadIndexedTex(level, texptr, 4, dstFmt, bufw);
|
||||
break;
|
||||
|
||||
case GE_TFMT_4444:
|
||||
@@ -1330,10 +1318,10 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
|
||||
tmpTexBuf16.resize(len);
|
||||
tmpTexBufRearrange.resize(len);
|
||||
finalBuf = tmpTexBuf16.data();
|
||||
ConvertColors(finalBuf, Memory::GetPointer(texaddr), dstFmt, bufw * h);
|
||||
ConvertColors(finalBuf, texptr, dstFmt, bufw * h);
|
||||
} else {
|
||||
tmpTexBuf32.resize(std::max(bufw, w) * h);
|
||||
finalBuf = UnswizzleFromMem(texaddr, bufw, 2, level);
|
||||
finalBuf = UnswizzleFromMem(texptr, bufw, 2, level);
|
||||
ConvertColors(finalBuf, finalBuf, dstFmt, bufw * h);
|
||||
}
|
||||
break;
|
||||
@@ -1342,18 +1330,18 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
|
||||
if (!gstate.isTextureSwizzled()) {
|
||||
// Special case: if we don't need to deal with packing, we don't need to copy.
|
||||
if ((g_Config.iTexScalingLevel == 1 && gl_extensions.EXT_unpack_subimage) || w == bufw) {
|
||||
finalBuf = Memory::GetPointer(texaddr);
|
||||
finalBuf = (void *)texptr;
|
||||
} else {
|
||||
int len = bufw * h;
|
||||
tmpTexBuf32.resize(std::max(bufw, w) * h);
|
||||
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
|
||||
Memory::Memcpy(tmpTexBuf32.data(), texaddr, len * sizeof(u32));
|
||||
memcpy(tmpTexBuf32.data(), texptr, len * sizeof(u32));
|
||||
finalBuf = tmpTexBuf32.data();
|
||||
}
|
||||
}
|
||||
else {
|
||||
tmpTexBuf32.resize(std::max(bufw, w) * h);
|
||||
finalBuf = UnswizzleFromMem(texaddr, bufw, 4, level);
|
||||
finalBuf = UnswizzleFromMem(texptr, bufw, 4, level);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "TextureScaler.h"
|
||||
|
||||
struct VirtualFramebuffer;
|
||||
class FramebufferManager;
|
||||
|
||||
enum TextureFiltering {
|
||||
AUTO = 1,
|
||||
@@ -56,6 +57,10 @@ public:
|
||||
// are being rendered to. This is barebones so far.
|
||||
void NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg);
|
||||
|
||||
void SetFramebufferManager(FramebufferManager *fbManager) {
|
||||
framebufferManager_ = fbManager;
|
||||
}
|
||||
|
||||
size_t NumLoadedTextures() const {
|
||||
return cache.size();
|
||||
}
|
||||
@@ -115,8 +120,8 @@ private:
|
||||
};
|
||||
|
||||
void Decimate(); // Run this once per frame to get rid of old textures.
|
||||
void *UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u32 level);
|
||||
void *ReadIndexedTex(int level, u32 texaddr, int bytesPerIndex, GLuint dstFmt, int bufw);
|
||||
void *UnswizzleFromMem(const u8 *texptr, u32 bufw, u32 bytesPerPixel, u32 level);
|
||||
void *ReadIndexedTex(int level, const u8 *texptr, int bytesPerIndex, GLuint dstFmt, int bufw);
|
||||
void UpdateSamplingParams(TexCacheEntry &entry, bool force);
|
||||
void LoadTextureLevel(TexCacheEntry &entry, int level, bool replaceImages, GLenum dstFmt);
|
||||
GLenum GetDestFormat(GETextureFormat format, GEPaletteFormat clutFormat) const;
|
||||
@@ -160,5 +165,6 @@ private:
|
||||
float maxAnisotropyLevel;
|
||||
|
||||
int decimationCounter_;
|
||||
FramebufferManager *framebufferManager_;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user