1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Rewrite textures loading and mapping:

- use RiceVideo method for texture size calculation.
  RiceVideo uses the same method for texture dumping.
- rewrite texture mapping.
  Texture Clamp-Wrap-Mirror implemented in shaders.

Problem explanation:
https://github.com/gonetz/GLideN64/issues/1885#issuecomment-485136358

Fixed various glitches with HD textures, #1885
This commit is contained in:
Sergey Lipskiy 2019-05-08 21:04:24 +07:00
parent 993960f9ea
commit 2d712f2ae0
25 changed files with 500 additions and 387 deletions

View File

@ -77,15 +77,15 @@ void ColorBufferToRDRAM::_initFBTexture(void)
m_pTexture->mirrorT = 0; m_pTexture->mirrorT = 0;
//The actual VI width is not used for texture width because most texture widths //The actual VI width is not used for texture width because most texture widths
//cause slowdowns in the glReadPixels call, at least on Android //cause slowdowns in the glReadPixels call, at least on Android
m_pTexture->realWidth = m_lastBufferWidth; m_pTexture->width = m_lastBufferWidth;
m_pTexture->realHeight = VI_GetMaxBufferHeight(m_lastBufferWidth); m_pTexture->height = VI_GetMaxBufferHeight(m_lastBufferWidth);
m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormat.colorFormatBytes; m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormat.colorFormatBytes;
{ {
Context::InitTextureParams params; Context::InitTextureParams params;
params.handle = m_pTexture->name; params.handle = m_pTexture->name;
params.width = m_pTexture->realWidth; params.width = m_pTexture->width;
params.height = m_pTexture->realHeight; params.height = m_pTexture->height;
params.internalFormat = fbTexFormat.colorInternalFormat; params.internalFormat = fbTexFormat.colorInternalFormat;
params.format = fbTexFormat.colorFormat; params.format = fbTexFormat.colorFormat;
params.dataType = fbTexFormat.colorType; params.dataType = fbTexFormat.colorType;
@ -157,8 +157,8 @@ bool ColorBufferToRDRAM::_prepareCopy(u32& _startAddress)
return false; return false;
if(m_pTexture == nullptr || if(m_pTexture == nullptr ||
m_pTexture->realWidth != _getRealWidth(pBuffer->m_width) || m_pTexture->width != _getRealWidth(pBuffer->m_width) ||
m_pTexture->realHeight != VI_GetMaxBufferHeight(_getRealWidth(pBuffer->m_width))) m_pTexture->height != VI_GetMaxBufferHeight(_getRealWidth(pBuffer->m_width)))
{ {
_destroyFBTexure(); _destroyFBTexure();
@ -193,7 +193,7 @@ bool ColorBufferToRDRAM::_prepareCopy(u32& _startAddress)
x0 = (screenWidth - width) / 2; x0 = (screenWidth - width) / 2;
} }
} else { } else {
width = m_pCurFrameBuffer->m_pTexture->realWidth; width = m_pCurFrameBuffer->m_pTexture->width;
} }
u32 height = (u32)(bufferHeight * m_pCurFrameBuffer->m_scale); u32 height = (u32)(bufferHeight * m_pCurFrameBuffer->m_scale);
@ -203,14 +203,14 @@ bool ColorBufferToRDRAM::_prepareCopy(u32& _startAddress)
blitParams.srcY0 = 0; blitParams.srcY0 = 0;
blitParams.srcX1 = x0 + width; blitParams.srcX1 = x0 + width;
blitParams.srcY1 = height; blitParams.srcY1 = height;
blitParams.srcWidth = pInputTexture->realWidth; blitParams.srcWidth = pInputTexture->width;
blitParams.srcHeight = pInputTexture->realHeight; blitParams.srcHeight = pInputTexture->height;
blitParams.dstX0 = 0; blitParams.dstX0 = 0;
blitParams.dstY0 = 0; blitParams.dstY0 = 0;
blitParams.dstX1 = m_pCurFrameBuffer->m_width; blitParams.dstX1 = m_pCurFrameBuffer->m_width;
blitParams.dstY1 = bufferHeight; blitParams.dstY1 = bufferHeight;
blitParams.dstWidth = m_pTexture->realWidth; blitParams.dstWidth = m_pTexture->width;
blitParams.dstHeight = m_pTexture->realHeight; blitParams.dstHeight = m_pTexture->height;
blitParams.filter = textureParameters::FILTER_NEAREST; blitParams.filter = textureParameters::FILTER_NEAREST;
blitParams.tex[0] = pInputTexture; blitParams.tex[0] = pInputTexture;
blitParams.combiner = CombinerInfo::get().getTexrectCopyProgram(); blitParams.combiner = CombinerInfo::get().getTexrectCopyProgram();

View File

@ -59,9 +59,9 @@ void DepthBufferToRDRAM::init()
m_pColorTexture->maskT = 0; m_pColorTexture->maskT = 0;
m_pColorTexture->mirrorS = 0; m_pColorTexture->mirrorS = 0;
m_pColorTexture->mirrorT = 0; m_pColorTexture->mirrorT = 0;
m_pColorTexture->realWidth = DEPTH_TEX_WIDTH; m_pColorTexture->width = DEPTH_TEX_WIDTH;
m_pColorTexture->realHeight = DEPTH_TEX_HEIGHT; m_pColorTexture->height = DEPTH_TEX_HEIGHT;
m_pColorTexture->textureBytes = m_pColorTexture->realWidth * m_pColorTexture->realHeight; m_pColorTexture->textureBytes = m_pColorTexture->width * m_pColorTexture->height;
m_pDepthTexture = textureCache().addFrameBufferTexture(false); m_pDepthTexture = textureCache().addFrameBufferTexture(false);
m_pDepthTexture->format = G_IM_FMT_I; m_pDepthTexture->format = G_IM_FMT_I;
@ -73,16 +73,16 @@ void DepthBufferToRDRAM::init()
m_pDepthTexture->maskT = 0; m_pDepthTexture->maskT = 0;
m_pDepthTexture->mirrorS = 0; m_pDepthTexture->mirrorS = 0;
m_pDepthTexture->mirrorT = 0; m_pDepthTexture->mirrorT = 0;
m_pDepthTexture->realWidth = DEPTH_TEX_WIDTH; m_pDepthTexture->width = DEPTH_TEX_WIDTH;
m_pDepthTexture->realHeight = DEPTH_TEX_HEIGHT; m_pDepthTexture->height = DEPTH_TEX_HEIGHT;
m_pDepthTexture->textureBytes = m_pDepthTexture->realWidth * m_pDepthTexture->realHeight * sizeof(float); m_pDepthTexture->textureBytes = m_pDepthTexture->width * m_pDepthTexture->height * sizeof(float);
const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats(); const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats();
Context::InitTextureParams initParams; Context::InitTextureParams initParams;
initParams.handle = m_pColorTexture->name; initParams.handle = m_pColorTexture->name;
initParams.textureUnitIndex = textureIndices::Tex[0]; initParams.textureUnitIndex = textureIndices::Tex[0];
initParams.width = m_pColorTexture->realWidth; initParams.width = m_pColorTexture->width;
initParams.height = m_pColorTexture->realHeight; initParams.height = m_pColorTexture->height;
initParams.internalFormat = fbTexFormats.monochromeInternalFormat; initParams.internalFormat = fbTexFormats.monochromeInternalFormat;
initParams.format = fbTexFormats.monochromeFormat; initParams.format = fbTexFormats.monochromeFormat;
initParams.dataType = fbTexFormats.monochromeType; initParams.dataType = fbTexFormats.monochromeType;
@ -97,8 +97,8 @@ void DepthBufferToRDRAM::init()
gfxContext.setTextureParameters(setParams); gfxContext.setTextureParameters(setParams);
initParams.handle = m_pDepthTexture->name; initParams.handle = m_pDepthTexture->name;
initParams.width = m_pDepthTexture->realWidth; initParams.width = m_pDepthTexture->width;
initParams.height = m_pDepthTexture->realHeight; initParams.height = m_pDepthTexture->height;
initParams.internalFormat = fbTexFormats.depthInternalFormat; initParams.internalFormat = fbTexFormats.depthInternalFormat;
initParams.format = fbTexFormats.depthFormat; initParams.format = fbTexFormats.depthFormat;
initParams.dataType = fbTexFormats.depthType; initParams.dataType = fbTexFormats.depthType;
@ -189,7 +189,7 @@ bool DepthBufferToRDRAM::_prepareCopy(u32& _startAddress, bool _copyChunk)
blitParams.drawBuffer = m_FBO; blitParams.drawBuffer = m_FBO;
blitParams.srcX0 = 0; blitParams.srcX0 = 0;
blitParams.srcY0 = 0; blitParams.srcY0 = 0;
blitParams.srcX1 = m_pCurFrameBuffer->m_pTexture->realWidth; blitParams.srcX1 = m_pCurFrameBuffer->m_pTexture->width;
blitParams.srcY1 = s32(m_pCurFrameBuffer->m_height * m_pCurFrameBuffer->m_scale); blitParams.srcY1 = s32(m_pCurFrameBuffer->m_height * m_pCurFrameBuffer->m_scale);
blitParams.dstX0 = 0; blitParams.dstX0 = 0;
blitParams.dstY0 = 0; blitParams.dstY0 = 0;

View File

@ -41,14 +41,14 @@ void RDRAMtoColorBuffer::init()
m_pTexture->maskT = 0; m_pTexture->maskT = 0;
m_pTexture->mirrorS = 0; m_pTexture->mirrorS = 0;
m_pTexture->mirrorT = 0; m_pTexture->mirrorT = 0;
m_pTexture->realWidth = 640; m_pTexture->width = 640;
m_pTexture->realHeight = 580; m_pTexture->height = 580;
m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormats.colorFormatBytes; m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormats.colorFormatBytes;
Context::InitTextureParams initParams; Context::InitTextureParams initParams;
initParams.handle = m_pTexture->name; initParams.handle = m_pTexture->name;
initParams.width = m_pTexture->realWidth; initParams.width = m_pTexture->width;
initParams.height = m_pTexture->realHeight; initParams.height = m_pTexture->height;
initParams.internalFormat = fbTexFormats.colorInternalFormat; initParams.internalFormat = fbTexFormats.colorInternalFormat;
initParams.format = fbTexFormats.colorFormat; initParams.format = fbTexFormats.colorFormat;
initParams.dataType = fbTexFormats.colorType; initParams.dataType = fbTexFormats.colorType;
@ -185,9 +185,6 @@ void RDRAMtoColorBuffer::_copyFromRDRAM(u32 _height, bool _fullAlpha)
const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats(); const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats();
m_pTexture->width = width;
m_pTexture->height = height;
u32 * pDst = nullptr; u32 * pDst = nullptr;
std::unique_ptr<u8[]> dstData; std::unique_ptr<u8[]> dstData;
@ -254,8 +251,8 @@ void RDRAMtoColorBuffer::_copyFromRDRAM(u32 _height, bool _fullAlpha)
updateParams.data = m_pbuf; updateParams.data = m_pbuf;
gfxContext.update2DTexture(updateParams); gfxContext.update2DTexture(updateParams);
m_pTexture->scaleS = 1.0f / (float)m_pTexture->realWidth; m_pTexture->scaleS = 1.0f / (float)m_pTexture->width;
m_pTexture->scaleT = 1.0f / (float)m_pTexture->realHeight; m_pTexture->scaleT = 1.0f / (float)m_pTexture->height;
m_pTexture->shiftScaleS = 1.0f; m_pTexture->shiftScaleS = 1.0f;
m_pTexture->shiftScaleT = 1.0f; m_pTexture->shiftScaleT = 1.0f;
m_pTexture->offsetS = 0.0f; m_pTexture->offsetS = 0.0f;

View File

@ -618,7 +618,7 @@ void Debugger::_drawFrameBuffer(FrameBuffer * _pBuffer)
pBufferTexture = _pBuffer->m_pResolveTexture; pBufferTexture = _pBuffer->m_pResolveTexture;
} }
s32 srcCoord[4] = { 0, 0, pBufferTexture->realWidth, (s32)(_pBuffer->m_height * _pBuffer->m_scale) }; s32 srcCoord[4] = { 0, 0, pBufferTexture->width, (s32)(_pBuffer->m_height * _pBuffer->m_scale) };
const s32 hOffset = (wnd.getScreenWidth() - wnd.getWidth()) / 2; const s32 hOffset = (wnd.getScreenWidth() - wnd.getWidth()) / 2;
const s32 vOffset = (wnd.getScreenHeight() - wnd.getHeight()) / 2 + wnd.getHeightOffset() + wnd.getHeight()*3/8; const s32 vOffset = (wnd.getScreenHeight() - wnd.getHeight()) / 2 + wnd.getHeightOffset() + wnd.getHeight()*3/8;
s32 dstCoord[4] = { hOffset, vOffset, hOffset + (s32)wnd.getWidth()*5/8, vOffset + (s32)wnd.getHeight()*5/8 }; s32 dstCoord[4] = { hOffset, vOffset, hOffset + (s32)wnd.getWidth()*5/8, vOffset + (s32)wnd.getHeight()*5/8 };
@ -635,8 +635,8 @@ void Debugger::_drawFrameBuffer(FrameBuffer * _pBuffer)
blitParams.srcY0 = srcCoord[3]; blitParams.srcY0 = srcCoord[3];
blitParams.srcX1 = srcCoord[2]; blitParams.srcX1 = srcCoord[2];
blitParams.srcY1 = srcCoord[1]; blitParams.srcY1 = srcCoord[1];
blitParams.srcWidth = pBufferTexture->realWidth; blitParams.srcWidth = pBufferTexture->width;
blitParams.srcHeight = pBufferTexture->realHeight; blitParams.srcHeight = pBufferTexture->height;
blitParams.dstX0 = dstCoord[0]; blitParams.dstX0 = dstCoord[0];
blitParams.dstY0 = dstCoord[1]; blitParams.dstY0 = dstCoord[1];
blitParams.dstX1 = dstCoord[2]; blitParams.dstX1 = dstCoord[2];

View File

@ -64,15 +64,13 @@ void DepthBuffer::_initDepthImageTexture(FrameBuffer * _pBuffer, CachedTexture&
_cachedTexture.maskT = 0; _cachedTexture.maskT = 0;
_cachedTexture.mirrorS = 0; _cachedTexture.mirrorS = 0;
_cachedTexture.mirrorT = 0; _cachedTexture.mirrorT = 0;
_cachedTexture.realWidth = _cachedTexture.width; _cachedTexture.textureBytes = _cachedTexture.width * _cachedTexture.height * fbTexFormat.depthImageFormatBytes;
_cachedTexture.realHeight = _cachedTexture.height;
_cachedTexture.textureBytes = _cachedTexture.realWidth * _cachedTexture.realHeight * fbTexFormat.depthImageFormatBytes;
{ {
Context::InitTextureParams params; Context::InitTextureParams params;
params.handle = _cachedTexture.name; params.handle = _cachedTexture.name;
params.width = _cachedTexture.realWidth; params.width = _cachedTexture.width;
params.height = _cachedTexture.realHeight; params.height = _cachedTexture.height;
params.internalFormat = fbTexFormat.depthImageInternalFormat; params.internalFormat = fbTexFormat.depthImageInternalFormat;
params.format = fbTexFormat.depthImageFormat; params.format = fbTexFormat.depthImageFormat;
params.dataType = fbTexFormat.depthImageType; params.dataType = fbTexFormat.depthImageType;
@ -146,15 +144,13 @@ void DepthBuffer::_initDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture
_pTexture->maskT = 0; _pTexture->maskT = 0;
_pTexture->mirrorS = 0; _pTexture->mirrorS = 0;
_pTexture->mirrorT = 0; _pTexture->mirrorT = 0;
_pTexture->realWidth = _pTexture->width; _pTexture->textureBytes = _pTexture->width * _pTexture->height * fbTexFormat.depthFormatBytes;
_pTexture->realHeight = _pTexture->height;
_pTexture->textureBytes = _pTexture->realWidth * _pTexture->realHeight * fbTexFormat.depthFormatBytes;
Context::InitTextureParams initParams; Context::InitTextureParams initParams;
initParams.handle = _pTexture->name; initParams.handle = _pTexture->name;
initParams.msaaLevel = _multisample ? config.video.multisampling : 0U; initParams.msaaLevel = _multisample ? config.video.multisampling : 0U;
initParams.width = _pTexture->realWidth; initParams.width = _pTexture->width;
initParams.height = _pTexture->realHeight; initParams.height = _pTexture->height;
initParams.internalFormat = fbTexFormat.depthInternalFormat; initParams.internalFormat = fbTexFormat.depthInternalFormat;
initParams.format = fbTexFormat.depthFormat; initParams.format = fbTexFormat.depthFormat;
initParams.dataType = fbTexFormat.depthType; initParams.dataType = fbTexFormat.depthType;
@ -259,12 +255,12 @@ CachedTexture * DepthBuffer::resolveDepthBufferTexture(FrameBuffer * _pBuffer)
blitParams.drawBuffer = _pBuffer->m_resolveFBO; blitParams.drawBuffer = _pBuffer->m_resolveFBO;
blitParams.srcX0 = 0; blitParams.srcX0 = 0;
blitParams.srcY0 = 0; blitParams.srcY0 = 0;
blitParams.srcX1 = m_pDepthBufferTexture->realWidth; blitParams.srcX1 = m_pDepthBufferTexture->width;
blitParams.srcY1 = m_pDepthBufferTexture->realHeight; blitParams.srcY1 = m_pDepthBufferTexture->height;
blitParams.dstX0 = 0; blitParams.dstX0 = 0;
blitParams.dstY0 = 0; blitParams.dstY0 = 0;
blitParams.dstX1 = m_pResolveDepthBufferTexture->realWidth; blitParams.dstX1 = m_pResolveDepthBufferTexture->width;
blitParams.dstY1 = m_pResolveDepthBufferTexture->realHeight; blitParams.dstY1 = m_pResolveDepthBufferTexture->height;
blitParams.mask = blitMask::DEPTH_BUFFER; blitParams.mask = blitMask::DEPTH_BUFFER;
blitParams.filter = textureParameters::FILTER_NEAREST; blitParams.filter = textureParameters::FILTER_NEAREST;
@ -310,12 +306,12 @@ CachedTexture * DepthBuffer::copyDepthBufferTexture(FrameBuffer * _pBuffer)
blitParams.drawBuffer = m_copyFBO; blitParams.drawBuffer = m_copyFBO;
blitParams.srcX0 = 0; blitParams.srcX0 = 0;
blitParams.srcY0 = 0; blitParams.srcY0 = 0;
blitParams.srcX1 = m_pDepthBufferTexture->realWidth; blitParams.srcX1 = m_pDepthBufferTexture->width;
blitParams.srcY1 = m_pDepthBufferTexture->realHeight; blitParams.srcY1 = m_pDepthBufferTexture->height;
blitParams.dstX0 = 0; blitParams.dstX0 = 0;
blitParams.dstY0 = 0; blitParams.dstY0 = 0;
blitParams.dstX1 = m_pDepthBufferTexture->realWidth; blitParams.dstX1 = m_pDepthBufferTexture->width;
blitParams.dstY1 = m_pDepthBufferTexture->realHeight; blitParams.dstY1 = m_pDepthBufferTexture->height;
blitParams.mask = blitMask::DEPTH_BUFFER; blitParams.mask = blitMask::DEPTH_BUFFER;
blitParams.filter = textureParameters::FILTER_NEAREST; blitParams.filter = textureParameters::FILTER_NEAREST;
@ -507,7 +503,7 @@ void DepthBufferList::clearBuffer()
return; return;
DepthBuffer * pDepthBuffer = pColorBuffer->m_pDepthBuffer; DepthBuffer * pDepthBuffer = pColorBuffer->m_pDepthBuffer;
//if (pColorBuffer->m_pTexture->realWidth == pDepthBuffer->m_pDepthImageZTexture->realWidth) //if (pColorBuffer->m_pTexture->realWidth == pDepthBuffer->m_pDepthImageZTexture->realWidth)
{ {
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, pDepthBuffer->m_ZTextureClearFBO); gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, pDepthBuffer->m_ZTextureClearFBO);
gfxContext.clearColorBuffer(1.0f, 0.0f, 0.0f, 0.0f); gfxContext.clearColorBuffer(1.0f, 0.0f, 0.0f, 0.0f);

View File

@ -98,9 +98,7 @@ void _initFrameBufferTexture(u32 _address, u16 _width, u16 _height, f32 _scale,
_pTexture->maskT = 0; _pTexture->maskT = 0;
_pTexture->mirrorS = 0; _pTexture->mirrorS = 0;
_pTexture->mirrorT = 0; _pTexture->mirrorT = 0;
_pTexture->realWidth = _pTexture->width; _pTexture->textureBytes = _pTexture->width * _pTexture->height;
_pTexture->realHeight = _pTexture->height;
_pTexture->textureBytes = _pTexture->realWidth * _pTexture->realHeight;
if (_size > G_IM_SIZ_8b) if (_size > G_IM_SIZ_8b)
_pTexture->textureBytes *= fbTexFormats.colorFormatBytes; _pTexture->textureBytes *= fbTexFormats.colorFormatBytes;
else else
@ -121,8 +119,8 @@ void _setAndAttachBufferTexture(ObjectHandle _fbo, CachedTexture *_pTexture, u32
initParams.textureUnitIndex = textureIndices::Tex[_t]; initParams.textureUnitIndex = textureIndices::Tex[_t];
if (_multisampling) if (_multisampling)
initParams.msaaLevel = config.video.multisampling; initParams.msaaLevel = config.video.multisampling;
initParams.width = _pTexture->realWidth; initParams.width = _pTexture->width;
initParams.height = _pTexture->realHeight; initParams.height = _pTexture->height;
if (_pTexture->size > G_IM_SIZ_8b) { if (_pTexture->size > G_IM_SIZ_8b) {
initParams.internalFormat = fbTexFormat.colorInternalFormat; initParams.internalFormat = fbTexFormat.colorInternalFormat;
initParams.format = fbTexFormat.colorFormat; initParams.format = fbTexFormat.colorFormat;
@ -331,12 +329,12 @@ void FrameBuffer::resolveMultisampledTexture(bool _bForce)
blitParams.drawBuffer = m_resolveFBO; blitParams.drawBuffer = m_resolveFBO;
blitParams.srcX0 = 0; blitParams.srcX0 = 0;
blitParams.srcY0 = 0; blitParams.srcY0 = 0;
blitParams.srcX1 = m_pTexture->realWidth; blitParams.srcX1 = m_pTexture->width;
blitParams.srcY1 = m_pTexture->realHeight; blitParams.srcY1 = m_pTexture->height;
blitParams.dstX0 = 0; blitParams.dstX0 = 0;
blitParams.dstY0 = 0; blitParams.dstY0 = 0;
blitParams.dstX1 = m_pResolveTexture->realWidth; blitParams.dstX1 = m_pResolveTexture->width;
blitParams.dstY1 = m_pResolveTexture->realHeight; blitParams.dstY1 = m_pResolveTexture->height;
blitParams.mask = blitMask::COLOR_BUFFER; blitParams.mask = blitMask::COLOR_BUFFER;
blitParams.filter = textureParameters::FILTER_NEAREST; blitParams.filter = textureParameters::FILTER_NEAREST;
@ -391,12 +389,12 @@ CachedTexture * FrameBuffer::_getSubTexture(u32 _t)
s32 x0 = (s32)(m_pTexture->offsetS * m_scale); s32 x0 = (s32)(m_pTexture->offsetS * m_scale);
s32 y0 = (s32)(m_pTexture->offsetT * m_scale); s32 y0 = (s32)(m_pTexture->offsetT * m_scale);
s32 copyWidth = m_pSubTexture->realWidth; s32 copyWidth = m_pSubTexture->width;
if (x0 + copyWidth > m_pTexture->realWidth) if (x0 + copyWidth > m_pTexture->width)
copyWidth = m_pTexture->realWidth - x0; copyWidth = m_pTexture->width - x0;
s32 copyHeight = m_pSubTexture->realHeight; s32 copyHeight = m_pSubTexture->height;
if (y0 + copyHeight > m_pTexture->realHeight) if (y0 + copyHeight > m_pTexture->height)
copyHeight = m_pTexture->realHeight - y0; copyHeight = m_pTexture->height - y0;
ObjectHandle readFBO = m_FBO; ObjectHandle readFBO = m_FBO;
if (Context::WeakBlitFramebuffer && if (Context::WeakBlitFramebuffer &&
@ -451,12 +449,12 @@ CachedTexture * FrameBuffer::_copyFrameBufferTexture()
blitParams.drawBuffer = m_copyFBO; blitParams.drawBuffer = m_copyFBO;
blitParams.srcX0 = 0; blitParams.srcX0 = 0;
blitParams.srcY0 = 0; blitParams.srcY0 = 0;
blitParams.srcX1 = m_pTexture->realWidth; blitParams.srcX1 = m_pTexture->width;
blitParams.srcY1 = m_pTexture->realHeight; blitParams.srcY1 = m_pTexture->height;
blitParams.dstX0 = 0; blitParams.dstX0 = 0;
blitParams.dstY0 = 0; blitParams.dstY0 = 0;
blitParams.dstX1 = m_pTexture->realWidth; blitParams.dstX1 = m_pTexture->width;
blitParams.dstY1 = m_pTexture->realHeight; blitParams.dstY1 = m_pTexture->height;
blitParams.mask = blitMask::COLOR_BUFFER; blitParams.mask = blitMask::COLOR_BUFFER;
blitParams.filter = textureParameters::FILTER_NEAREST; blitParams.filter = textureParameters::FILTER_NEAREST;
@ -497,8 +495,8 @@ CachedTexture * FrameBuffer::getTexture(u32 _t)
if (!getDepthTexture && (gSP.textureTile[_t]->clamps == 0 || gSP.textureTile[_t]->clampt == 0)) if (!getDepthTexture && (gSP.textureTile[_t]->clamps == 0 || gSP.textureTile[_t]->clampt == 0))
pTexture = _getSubTexture(_t); pTexture = _getSubTexture(_t);
pTexture->scaleS = m_scale / (float)pTexture->realWidth; pTexture->scaleS = m_scale / (float)pTexture->width;
pTexture->scaleT = m_scale / (float)pTexture->realHeight; pTexture->scaleT = m_scale / (float)pTexture->height;
if (gSP.textureTile[_t]->shifts > 10) if (gSP.textureTile[_t]->shifts > 10)
pTexture->shiftScaleS = (float)(1 << (16 - gSP.textureTile[_t]->shifts)); pTexture->shiftScaleS = (float)(1 << (16 - gSP.textureTile[_t]->shifts));
@ -528,8 +526,8 @@ CachedTexture * FrameBuffer::getTextureBG(u32 _t)
pTexture = _copyFrameBufferTexture(); pTexture = _copyFrameBufferTexture();
} }
pTexture->scaleS = m_scale / (float)pTexture->realWidth; pTexture->scaleS = m_scale / (float)pTexture->width;
pTexture->scaleT = m_scale / (float)pTexture->realHeight; pTexture->scaleT = m_scale / (float)pTexture->height;
pTexture->shiftScaleS = 1.0f; pTexture->shiftScaleS = 1.0f;
pTexture->shiftScaleT = 1.0f; pTexture->shiftScaleT = 1.0f;
@ -920,12 +918,12 @@ void FrameBufferList::attachDepthBuffer()
bool goodDepthBufferTexture = false; bool goodDepthBufferTexture = false;
if (Context::DepthFramebufferTextures) { if (Context::DepthFramebufferTextures) {
if (Context::WeakBlitFramebuffer) if (Context::WeakBlitFramebuffer)
goodDepthBufferTexture = pDepthBuffer->m_pDepthBufferTexture->realWidth == pCurrent->m_pTexture->realWidth; goodDepthBufferTexture = pDepthBuffer->m_pDepthBufferTexture->width == pCurrent->m_pTexture->width;
else else
goodDepthBufferTexture = pDepthBuffer->m_pDepthBufferTexture->realWidth >= pCurrent->m_pTexture->realWidth || goodDepthBufferTexture = pDepthBuffer->m_pDepthBufferTexture->width >= pCurrent->m_pTexture->width ||
std::abs((s32)(pCurrent->m_width - pDepthBuffer->m_width)) < 2; std::abs((s32)(pCurrent->m_width - pDepthBuffer->m_width)) < 2;
} else { } else {
goodDepthBufferTexture = pDepthBuffer->m_depthRenderbufferWidth == pCurrent->m_pTexture->realWidth; goodDepthBufferTexture = pDepthBuffer->m_depthRenderbufferWidth == pCurrent->m_pTexture->width;
} }
if (goodDepthBufferTexture) { if (goodDepthBufferTexture) {
@ -1302,8 +1300,8 @@ void FrameBufferList::OverscanBuffer::draw(u32 _fullHeight, bool _PAL)
blitParams.srcY0 = static_cast<s32>(_fullHeight * m_scale) - bottom; blitParams.srcY0 = static_cast<s32>(_fullHeight * m_scale) - bottom;
blitParams.srcX1 = m_bufferWidth - right; blitParams.srcX1 = m_bufferWidth - right;
blitParams.srcY1 = top; blitParams.srcY1 = top;
blitParams.srcWidth = m_pTexture->realWidth; blitParams.srcWidth = m_pTexture->width;
blitParams.srcHeight = m_pTexture->realHeight; blitParams.srcHeight = m_pTexture->height;
blitParams.dstX0 = m_hOffset; blitParams.dstX0 = m_hOffset;
blitParams.dstY0 = m_vOffset + wnd.getHeightOffset(); blitParams.dstY0 = m_vOffset + wnd.getHeightOffset();
blitParams.dstX1 = m_hOffset + wnd.getWidth(); blitParams.dstX1 = m_hOffset + wnd.getWidth();
@ -1430,8 +1428,8 @@ void FrameBufferList::renderBuffer()
s32 srcCoord[4] = { (s32)((XoffsetLeft) * srcScaleX) + cutleft, s32 srcCoord[4] = { (s32)((XoffsetLeft) * srcScaleX) + cutleft,
(s32)(srcY0*srcScaleY), (s32)(srcY0*srcScaleY),
(s32)((srcWidth + XoffsetLeft - XoffsetRight) * srcScaleX) - cutright, (s32)((srcWidth + XoffsetLeft - XoffsetRight) * srcScaleX) - cutright,
min((s32)(srcY1*srcScaleY), (s32)pBufferTexture->realHeight) }; min((s32)(srcY1*srcScaleY), (s32)pBufferTexture->height) };
if (srcCoord[2] > pBufferTexture->realWidth || srcCoord[3] > pBufferTexture->realHeight) { if (srcCoord[2] > pBufferTexture->width || srcCoord[3] > pBufferTexture->height) {
removeBuffer(pBuffer->m_startAddress); removeBuffer(pBuffer->m_startAddress);
return; return;
} }
@ -1462,8 +1460,8 @@ void FrameBufferList::renderBuffer()
blitParams.srcY0 = srcCoord[1]; blitParams.srcY0 = srcCoord[1];
blitParams.srcX1 = srcCoord[2]; blitParams.srcX1 = srcCoord[2];
blitParams.srcY1 = srcCoord[3]; blitParams.srcY1 = srcCoord[3];
blitParams.srcWidth = pBufferTexture->realWidth; blitParams.srcWidth = pBufferTexture->width;
blitParams.srcHeight = pBufferTexture->realHeight; blitParams.srcHeight = pBufferTexture->height;
blitParams.dstX0 = dstCoord[0]; blitParams.dstX0 = dstCoord[0];
blitParams.dstY0 = dstCoord[1]; blitParams.dstY0 = dstCoord[1];
blitParams.dstX1 = dstCoord[2]; blitParams.dstX1 = dstCoord[2];
@ -1498,9 +1496,9 @@ void FrameBufferList::renderBuffer()
} }
blitParams.srcY0 = 0; blitParams.srcY0 = 0;
blitParams.srcY1 = min((s32)(srcY1*srcScaleY), (s32)pFilteredBuffer->m_pTexture->realHeight); blitParams.srcY1 = min((s32)(srcY1*srcScaleY), (s32)pFilteredBuffer->m_pTexture->height);
blitParams.srcWidth = pBufferTexture->realWidth; blitParams.srcWidth = pBufferTexture->width;
blitParams.srcHeight = pBufferTexture->realHeight; blitParams.srcHeight = pBufferTexture->height;
blitParams.dstY0 = vOffset + (s32)(dstY0*dstScaleY); blitParams.dstY0 = vOffset + (s32)(dstY0*dstScaleY);
blitParams.dstY1 = vOffset + (s32)(dstY1*dstScaleY); blitParams.dstY1 = vOffset + (s32)(dstY1*dstScaleY);
blitParams.dstWidth = m_overscan.getBufferWidth(); blitParams.dstWidth = m_overscan.getBufferWidth();

View File

@ -18,14 +18,14 @@ namespace graphics {
const u8* ColorBufferReader::_convertFloatTextureBuffer(const u8* _gpuData, u32 _width, u32 _height, const u8* ColorBufferReader::_convertFloatTextureBuffer(const u8* _gpuData, u32 _width, u32 _height,
u32 _heightOffset, u32 _stride) u32 _heightOffset, u32 _stride)
{ {
int bytesToCopy = m_pTexture->realWidth * _height * 16; int bytesToCopy = m_pTexture->width * _height * 16;
std::copy_n(_gpuData, bytesToCopy, m_tempPixelData.data()); std::copy_n(_gpuData, bytesToCopy, m_tempPixelData.data());
u8* pixelDataAlloc = m_pixelData.data(); u8* pixelDataAlloc = m_pixelData.data();
float* pixelData = reinterpret_cast<float*>(m_tempPixelData.data()); float* pixelData = reinterpret_cast<float*>(m_tempPixelData.data());
const u32 colorsPerPixel = 4; const u32 colorsPerPixel = 4;
const u32 widthPixels = _width * colorsPerPixel; const u32 widthPixels = _width * colorsPerPixel;
const u32 stridePixels = _stride * colorsPerPixel; const u32 stridePixels = _stride * colorsPerPixel;
if (_height * widthPixels > m_pixelData.size()) if (_height * widthPixels > m_pixelData.size())
_height = static_cast<u32>(m_pixelData.size()) / widthPixels; _height = static_cast<u32>(m_pixelData.size()) / widthPixels;
@ -47,7 +47,7 @@ namespace graphics {
const u32 strideBytes = _stride * _colorsPerPixel; const u32 strideBytes = _stride * _colorsPerPixel;
u8* pixelDataAlloc = m_pixelData.data(); u8* pixelDataAlloc = m_pixelData.data();
if (_height * widthBytes > m_pixelData.size()) if (_height * widthBytes > m_pixelData.size())
_height = static_cast<u32>(m_pixelData.size()) / widthBytes; _height = static_cast<u32>(m_pixelData.size()) / widthBytes;

View File

@ -269,8 +269,8 @@ public:
"uniform mediump vec2 uCacheShiftScale[2]; \n" "uniform mediump vec2 uCacheShiftScale[2]; \n"
"uniform lowp ivec2 uCacheFrameBuffer; \n" "uniform lowp ivec2 uCacheFrameBuffer; \n"
"OUT lowp vec4 vShadeColor; \n" "OUT lowp vec4 vShadeColor; \n"
"OUT highp vec2 vTexCoord0; \n" "OUT highp vec2 vTexCoord0; \n"
"OUT highp vec2 vTexCoord1; \n" "OUT highp vec2 vTexCoord1; \n"
"OUT mediump vec2 vLodTexCoord; \n" "OUT mediump vec2 vLodTexCoord; \n"
"OUT lowp float vNumLights; \n" "OUT lowp float vNumLights; \n"
@ -749,7 +749,17 @@ public:
"uniform lowp int uDepthSource; \n" "uniform lowp int uDepthSource; \n"
"uniform highp float uPrimDepth; \n" "uniform highp float uPrimDepth; \n"
"uniform mediump vec2 uScreenScale; \n" "uniform mediump vec2 uScreenScale; \n"
"uniform highp vec4 uTexClamp0; \n"
"uniform highp vec4 uTexClamp1; \n"
"uniform highp vec2 uTexWrap0; \n"
"uniform highp vec2 uTexWrap1; \n"
"uniform lowp vec2 uTexMirror0; \n"
"uniform lowp vec2 uTexMirror1; \n"
"uniform highp vec2 uTexScale0; \n"
"uniform highp vec2 uTexScale1; \n"
"uniform lowp int uFogUsage; \n" "uniform lowp int uFogUsage; \n"
"highp vec2 texCoord0; \n"
"highp vec2 texCoord1; \n"
; ;
if (config.generalEmulation.enableLegacyBlending == 0) { if (config.generalEmulation.enableLegacyBlending == 0) {
@ -938,6 +948,19 @@ public:
} }
}; };
class ShaderFragmentHeaderClampWrapMirror : public ShaderPart
{
public:
ShaderFragmentHeaderClampWrapMirror(const opengl::GLInfo & _glinfo)
{
m_part =
"highp vec2 clampWrapMirror(in highp vec2 vTexCoord, \n"
" in highp vec4 vClamp, in highp vec2 vWrap, \n"
" in lowp vec2 vMirror, in highp vec2 vOffset); \n"
;
}
};
class ShaderFragmentHeaderReadMSTex : public ShaderPart class ShaderFragmentHeaderReadMSTex : public ShaderPart
{ {
public: public:
@ -1297,6 +1320,28 @@ public:
} }
}; };
class ShaderFragmentClampWrapMirrorTex0 : public ShaderPart
{
public:
ShaderFragmentClampWrapMirrorTex0(const opengl::GLInfo & _glinfo)
{
m_part =
" texCoord0 = clampWrapMirror(vTexCoord0, uTexClamp0, uTexWrap0, uTexMirror0, uTexScale0); \n"
;
}
};
class ShaderFragmentClampWrapMirrorTex1 : public ShaderPart
{
public:
ShaderFragmentClampWrapMirrorTex1(const opengl::GLInfo & _glinfo)
{
m_part =
" texCoord1 = clampWrapMirror(vTexCoord1, uTexClamp1, uTexWrap1, uTexMirror1, uTexScale1); \n"
;
}
};
class ShaderFragmentReadTexMipmap : public ShaderPart class ShaderFragmentReadTexMipmap : public ShaderPart
{ {
public: public:
@ -1317,20 +1362,20 @@ public:
if (_glinfo.isGLES2) { if (_glinfo.isGLES2) {
m_part = m_part =
" nCurrentTile = 0; \n" " nCurrentTile = 0; \n"
" lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n" " lowp vec4 readtex0 = readTex(uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"
; ;
} else { } else {
if (config.video.multisampling > 0) { if (config.video.multisampling > 0) {
m_part = m_part =
" lowp vec4 readtex0; \n" " lowp vec4 readtex0; \n"
" if (uMSTexEnabled[0] == 0) { \n" " if (uMSTexEnabled[0] == 0) { \n"
" READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n" " READ_TEX(readtex0, uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
" } else readtex0 = readTexMS(uMSTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]);\n" " } else readtex0 = readTexMS(uMSTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]);\n"
; ;
} else { } else {
m_part = m_part =
" lowp vec4 readtex0; \n" " lowp vec4 readtex0; \n"
" READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n" " READ_TEX(readtex0, uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
; ;
} }
} }
@ -1352,27 +1397,27 @@ public:
shaderPart = " nCurrentTile = 0; \n"; shaderPart = " nCurrentTile = 0; \n";
if (g_textureConvert.getBilerp0()) { if (g_textureConvert.getBilerp0()) {
shaderPart += " lowp vec4 readtex0 = readTex(uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"; shaderPart += " lowp vec4 readtex0 = readTex(uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n";
} else { } else {
shaderPart += " lowp vec4 tmpTex = vec4(0.0); \n" shaderPart += " lowp vec4 tmpTex = vec4(0.0); \n"
" lowp vec4 readtex0 = YUV_Convert(uTex0, vTexCoord0, 0, uTextureFormat[0], tmpTex); \n"; " lowp vec4 readtex0 = YUV_Convert(uTex0, texCoord0, 0, uTextureFormat[0], tmpTex); \n";
} }
} else { } else {
if (!g_textureConvert.getBilerp0()) { if (!g_textureConvert.getBilerp0()) {
shaderPart = " lowp vec4 readtex0; \n" shaderPart = " lowp vec4 readtex0; \n"
" YUVCONVERT_TEX0(readtex0, uTex0, vTexCoord0, uTextureFormat[0]) \n"; " YUVCONVERT_TEX0(readtex0, uTex0, texCoord0, uTextureFormat[0]) \n";
} else { } else {
if (config.video.multisampling > 0) { if (config.video.multisampling > 0) {
shaderPart = shaderPart =
" lowp vec4 readtex0; \n" " lowp vec4 readtex0; \n"
" if (uMSTexEnabled[0] == 0) { \n" " if (uMSTexEnabled[0] == 0) { \n"
" READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n" " READ_TEX(readtex0, uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"
" } else readtex0 = readTexMS(uMSTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n"; " } else readtex0 = readTexMS(uMSTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]); \n";
} else { } else {
shaderPart = " lowp vec4 readtex0; \n" shaderPart = " lowp vec4 readtex0; \n"
" READ_TEX(readtex0, uTex0, vTexCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n"; " READ_TEX(readtex0, uTex0, texCoord0, uFbMonochrome[0], uFbFixedAlpha[0]) \n";
} }
} }
@ -1401,9 +1446,9 @@ public:
shaderPart = " nCurrentTile = 1; \n"; shaderPart = " nCurrentTile = 1; \n";
if (g_textureConvert.getBilerp1()) { if (g_textureConvert.getBilerp1()) {
shaderPart += " lowp vec4 readtex1 = readTex(uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"; shaderPart += " lowp vec4 readtex1 = readTex(uTex1, texCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n";
} else { } else {
shaderPart += " lowp vec4 readtex1 = YUV_Convert(uTex1, vTexCoord1, uTextureConvert, uTextureFormat[1], readtex0); \n"; shaderPart += " lowp vec4 readtex1 = YUV_Convert(uTex1, texCoord1, uTextureConvert, uTextureFormat[1], readtex0); \n";
} }
} else { } else {
@ -1411,17 +1456,17 @@ public:
if (!g_textureConvert.getBilerp1()) { if (!g_textureConvert.getBilerp1()) {
shaderPart = shaderPart =
" lowp vec4 readtex1; \n" " lowp vec4 readtex1; \n"
" YUVCONVERT_TEX1(readtex1, uTex1, vTexCoord1, uTextureFormat[1], readtex0) \n"; " YUVCONVERT_TEX1(readtex1, uTex1, texCoord1, uTextureFormat[1], readtex0) \n";
} else { } else {
if (config.video.multisampling > 0) { if (config.video.multisampling > 0) {
shaderPart = shaderPart =
" lowp vec4 readtex1; \n" " lowp vec4 readtex1; \n"
" if (uMSTexEnabled[1] == 0) { \n" " if (uMSTexEnabled[1] == 0) { \n"
" READ_TEX(readtex1, uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n" " READ_TEX(readtex1, uTex1, texCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n"
" } else readtex1 = readTexMS(uMSTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n"; " } else readtex1 = readTexMS(uMSTex1, texCoord1, uFbMonochrome[1], uFbFixedAlpha[1]); \n";
} else { } else {
shaderPart = " lowp vec4 readtex1; \n" shaderPart = " lowp vec4 readtex1; \n"
" READ_TEX(readtex1, uTex1, vTexCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n"; " READ_TEX(readtex1, uTex1, texCoord1, uFbMonochrome[1], uFbFixedAlpha[1]) \n";
} }
} }
@ -1651,8 +1696,8 @@ public:
"uniform mediump float uMinLod; \n" "uniform mediump float uMinLod; \n"
" \n" " \n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
" readtex0 = texture2D(uTex0, vTexCoord0); \n" " readtex0 = texture2D(uTex0, texCoord0); \n"
" readtex1 = texture2D(uTex1, vTexCoord1); \n" " readtex1 = texture2D(uTex1, texCoord1); \n"
" if (uMaxTile == 0) return 1.0; \n" " if (uMaxTile == 0) return 1.0; \n"
" return uMinLod; \n" " return uMinLod; \n"
"} \n" "} \n"
@ -1665,8 +1710,8 @@ public:
"uniform lowp int uTextureDetail; \n" "uniform lowp int uTextureDetail; \n"
" \n" " \n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
" readtex0 = texture2D(uTex0, vTexCoord0); \n" " readtex0 = texture2D(uTex0, texCoord0); \n"
" readtex1 = texture2DLodEXT(uTex1, vTexCoord1, 0.0); \n" " readtex1 = texture2DLodEXT(uTex1, texCoord1, 0.0); \n"
" \n" " \n"
" mediump float fMaxTile = float(uMaxTile); \n" " mediump float fMaxTile = float(uMaxTile); \n"
" mediump vec2 dx = abs(dFdx(vLodTexCoord)); \n" " mediump vec2 dx = abs(dFdx(vLodTexCoord)); \n"
@ -1695,9 +1740,9 @@ public:
" lod_tile = min(lod_tile, fMaxTile); \n" " lod_tile = min(lod_tile, fMaxTile); \n"
" lowp float lod_tile_m1 = max(0.0, lod_tile - 1.0); \n" " lowp float lod_tile_m1 = max(0.0, lod_tile - 1.0); \n"
" lowp float lod_tile_p1 = min(fMaxTile - 1.0, lod_tile + 1.0); \n" " lowp float lod_tile_p1 = min(fMaxTile - 1.0, lod_tile + 1.0); \n"
" lowp vec4 lodT = texture2DLodEXT(uTex1, vTexCoord1, lod_tile); \n" " lowp vec4 lodT = texture2DLodEXT(uTex1, texCoord1, lod_tile); \n"
" lowp vec4 lodT_m1 = texture2DLodEXT(uTex1, vTexCoord1, lod_tile_m1); \n" " lowp vec4 lodT_m1 = texture2DLodEXT(uTex1, texCoord1, lod_tile_m1); \n"
" lowp vec4 lodT_p1 = texture2DLodEXT(uTex1, vTexCoord1, lod_tile_p1); \n" " lowp vec4 lodT_p1 = texture2DLodEXT(uTex1, texCoord1, lod_tile_p1); \n"
" if (lod_tile < 1.0) { \n" " if (lod_tile < 1.0) { \n"
" if (magnify) { \n" " if (magnify) { \n"
// !sharpen && !detail // !sharpen && !detail
@ -1731,8 +1776,8 @@ public:
"uniform mediump float uMinLod; \n" "uniform mediump float uMinLod; \n"
" \n" " \n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
" readtex0 = texture(uTex0, vTexCoord0); \n" " readtex0 = texture(uTex0, texCoord0); \n"
" readtex1 = texture(uTex1, vTexCoord1); \n" " readtex1 = texture(uTex1, texCoord1); \n"
" if (uMaxTile == 0) return 1.0; \n" " if (uMaxTile == 0) return 1.0; \n"
" return uMinLod; \n" " return uMinLod; \n"
"} \n" "} \n"
@ -1777,8 +1822,8 @@ public:
"uniform lowp int uTextureDetail; \n" "uniform lowp int uTextureDetail; \n"
" \n" " \n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n" "mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1) { \n"
" READ_TEX_NORMAL(readtex0, uTex0, vTexCoord0, 0.0); \n" " READ_TEX_NORMAL(readtex0, uTex0, texCoord0, 0.0); \n"
" READ_TEX_MIPMAP(readtex1, uTex1, vTexCoord1, 0.0); \n" " READ_TEX_MIPMAP(readtex1, uTex1, texCoord1, 0.0); \n"
" \n" " \n"
" mediump float fMaxTile = float(uMaxTile); \n" " mediump float fMaxTile = float(uMaxTile); \n"
" mediump vec2 dx = abs(dFdx(vLodTexCoord)); \n" " mediump vec2 dx = abs(dFdx(vLodTexCoord)); \n"
@ -1808,9 +1853,9 @@ public:
" lowp float lod_tile_m1 = max(0.0, lod_tile - 1.0); \n" " lowp float lod_tile_m1 = max(0.0, lod_tile - 1.0); \n"
" lowp float lod_tile_p1 = min(fMaxTile - 1.0, lod_tile + 1.0); \n" " lowp float lod_tile_p1 = min(fMaxTile - 1.0, lod_tile + 1.0); \n"
" lowp vec4 lodT, lodT_m1, lodT_p1; \n" " lowp vec4 lodT, lodT_m1, lodT_p1; \n"
" READ_TEX_MIPMAP(lodT, uTex1, vTexCoord1, lod_tile); \n" " READ_TEX_MIPMAP(lodT, uTex1, texCoord1, lod_tile); \n"
" READ_TEX_MIPMAP(lodT_m1, uTex1, vTexCoord1, lod_tile_m1); \n" " READ_TEX_MIPMAP(lodT_m1, uTex1, texCoord1, lod_tile_m1); \n"
" READ_TEX_MIPMAP(lodT_p1, uTex1, vTexCoord1, lod_tile_p1); \n" " READ_TEX_MIPMAP(lodT_p1, uTex1, texCoord1, lod_tile_p1); \n"
" if (lod_tile < 1.0) { \n" " if (lod_tile < 1.0) { \n"
" if (magnify) { \n" " if (magnify) { \n"
// !sharpen && !detail // !sharpen && !detail
@ -2174,6 +2219,33 @@ public:
} }
}; };
class ShaderClampWrapMirror : public ShaderPart
{
public:
ShaderClampWrapMirror(const opengl::GLInfo & _glinfo)
{
m_part =
"highp vec2 clampWrapMirror(in highp vec2 vTexCoord, in highp vec4 vClamp, \n"
" in highp vec2 vWrap, in lowp vec2 vMirror, in highp vec2 vScale) \n"
"{ \n"
" highp vec2 texCoord = clamp(vTexCoord, vClamp.xy, vClamp.zw); \n"
" lowp vec2 one = vec2(1.0); \n"
" lowp vec2 clamped = step(vClamp.zw, texCoord); \n"
" lowp vec2 notClamped = one - clamped; \n"
" texCoord = clamped * texCoord + notClamped * mod(texCoord, vWrap); \n"
" highp vec2 intPart = floor(texCoord); \n"
" highp vec2 fractPart = fract(texCoord); \n"
" lowp vec2 needMirror = step(vec2(0.5), mod(intPart, vec2(2.0))) * vMirror; \n"
" texCoord = clamped * texCoord + notClamped * fractPart; \n"
" texCoord = (one - vMirror) * texCoord + vMirror * fractPart; \n"
" texCoord = (one - texCoord) * needMirror + texCoord * (one - needMirror); \n"
" texCoord *= vScale; \n"
" return texCoord; \n"
"} \n"
;
}
};
/*---------------ShaderPartsEnd-------------*/ /*---------------ShaderPartsEnd-------------*/
static static
@ -2339,6 +2411,7 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
m_fragmentHeaderWriteDepth->write(ssShader); m_fragmentHeaderWriteDepth->write(ssShader);
m_fragmentHeaderDepthCompare->write(ssShader); m_fragmentHeaderDepthCompare->write(ssShader);
m_fragmentHeaderReadMSTex->write(ssShader); m_fragmentHeaderReadMSTex->write(ssShader);
m_fragmentHeaderClampWrapMirror->write(ssShader);
if (bUseLod) if (bUseLod)
m_fragmentHeaderMipMap->write(ssShader); m_fragmentHeaderMipMap->write(ssShader);
else if (g_cycleType < G_CYC_COPY) else if (g_cycleType < G_CYC_COPY)
@ -2371,6 +2444,11 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
m_fragmentBlendMux->write(ssShader); m_fragmentBlendMux->write(ssShader);
if (bUseTextures) { if (bUseTextures) {
if (combinerInputs.usesTile(0))
m_fragmentClampWrapMirrorTex0->write(ssShader);
if (combinerInputs.usesTile(1))
m_fragmentClampWrapMirrorTex1->write(ssShader);
if (bUseLod) { if (bUseLod) {
m_fragmentReadTexMipmap->write(ssShader); m_fragmentReadTexMipmap->write(ssShader);
} else { } else {
@ -2408,6 +2486,7 @@ graphics::CombinerProgram * CombinerProgramBuilder::buildCombinerProgram(Combine
m_shaderCalcLight->write(ssShader); m_shaderCalcLight->write(ssShader);
if (bUseTextures) { if (bUseTextures) {
m_shaderClampWrapMirror->write(ssShader);
if (bUseLod) if (bUseLod)
m_shaderMipmap->write(ssShader); m_shaderMipmap->write(ssShader);
else { else {
@ -2518,6 +2597,7 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o
, m_fragmentHeaderWriteDepth(new ShaderFragmentHeaderWriteDepth(_glinfo)) , m_fragmentHeaderWriteDepth(new ShaderFragmentHeaderWriteDepth(_glinfo))
, m_fragmentHeaderCalcLight(new ShaderFragmentHeaderCalcLight(_glinfo)) , m_fragmentHeaderCalcLight(new ShaderFragmentHeaderCalcLight(_glinfo))
, m_fragmentHeaderMipMap(new ShaderFragmentHeaderMipMap(_glinfo)) , m_fragmentHeaderMipMap(new ShaderFragmentHeaderMipMap(_glinfo))
, m_fragmentHeaderClampWrapMirror(new ShaderFragmentHeaderClampWrapMirror(_glinfo))
, m_fragmentHeaderReadMSTex(new ShaderFragmentHeaderReadMSTex(_glinfo)) , m_fragmentHeaderReadMSTex(new ShaderFragmentHeaderReadMSTex(_glinfo))
, m_fragmentHeaderDither(new ShaderFragmentHeaderDither(_glinfo)) , m_fragmentHeaderDither(new ShaderFragmentHeaderDither(_glinfo))
, m_fragmentHeaderDepthCompare(new ShaderFragmentHeaderDepthCompare(_glinfo)) , m_fragmentHeaderDepthCompare(new ShaderFragmentHeaderDepthCompare(_glinfo))
@ -2528,6 +2608,8 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o
, m_fragmentBlendMux(new ShaderFragmentBlendMux(_glinfo)) , m_fragmentBlendMux(new ShaderFragmentBlendMux(_glinfo))
, m_fragmentReadTex0(new ShaderFragmentReadTex0(_glinfo)) , m_fragmentReadTex0(new ShaderFragmentReadTex0(_glinfo))
, m_fragmentReadTex1(new ShaderFragmentReadTex1(_glinfo)) , m_fragmentReadTex1(new ShaderFragmentReadTex1(_glinfo))
, m_fragmentClampWrapMirrorTex0(new ShaderFragmentClampWrapMirrorTex0(_glinfo))
, m_fragmentClampWrapMirrorTex1(new ShaderFragmentClampWrapMirrorTex1(_glinfo))
, m_fragmentReadTexCopyMode(new ShaderFragmentReadTexCopyMode(_glinfo)) , m_fragmentReadTexCopyMode(new ShaderFragmentReadTexCopyMode(_glinfo))
, m_fragmentReadTexMipmap(new ShaderFragmentReadTexMipmap(_glinfo)) , m_fragmentReadTexMipmap(new ShaderFragmentReadTexMipmap(_glinfo))
, m_fragmentCallN64Depth(new ShaderFragmentCallN64Depth(_glinfo)) , m_fragmentCallN64Depth(new ShaderFragmentCallN64Depth(_glinfo))
@ -2542,6 +2624,7 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o
, m_shaderReadtexCopyMode(new ShaderReadtexCopyMode(_glinfo)) , m_shaderReadtexCopyMode(new ShaderReadtexCopyMode(_glinfo))
, m_shaderN64DepthCompare(new ShaderN64DepthCompare(_glinfo)) , m_shaderN64DepthCompare(new ShaderN64DepthCompare(_glinfo))
, m_shaderN64DepthRender(new ShaderN64DepthRender(_glinfo)) , m_shaderN64DepthRender(new ShaderN64DepthRender(_glinfo))
, m_shaderClampWrapMirror(new ShaderClampWrapMirror(_glinfo))
, m_useProgram(_useProgram) , m_useProgram(_useProgram)
, m_combinerOptionsBits(graphics::CombinerProgram::getShaderCombinerOptionsBits()) , m_combinerOptionsBits(graphics::CombinerProgram::getShaderCombinerOptionsBits())
{ {

View File

@ -62,6 +62,7 @@ namespace glsl {
ShaderPartPtr m_fragmentHeaderWriteDepth; ShaderPartPtr m_fragmentHeaderWriteDepth;
ShaderPartPtr m_fragmentHeaderCalcLight; ShaderPartPtr m_fragmentHeaderCalcLight;
ShaderPartPtr m_fragmentHeaderMipMap; ShaderPartPtr m_fragmentHeaderMipMap;
ShaderPartPtr m_fragmentHeaderClampWrapMirror;
ShaderPartPtr m_fragmentHeaderReadMSTex; ShaderPartPtr m_fragmentHeaderReadMSTex;
ShaderPartPtr m_fragmentHeaderDither; ShaderPartPtr m_fragmentHeaderDither;
ShaderPartPtr m_fragmentHeaderDepthCompare; ShaderPartPtr m_fragmentHeaderDepthCompare;
@ -72,6 +73,8 @@ namespace glsl {
ShaderPartPtr m_fragmentBlendMux; ShaderPartPtr m_fragmentBlendMux;
ShaderPartPtr m_fragmentReadTex0; ShaderPartPtr m_fragmentReadTex0;
ShaderPartPtr m_fragmentReadTex1; ShaderPartPtr m_fragmentReadTex1;
ShaderPartPtr m_fragmentClampWrapMirrorTex0;
ShaderPartPtr m_fragmentClampWrapMirrorTex1;
ShaderPartPtr m_fragmentReadTexCopyMode; ShaderPartPtr m_fragmentReadTexCopyMode;
ShaderPartPtr m_fragmentReadTexMipmap; ShaderPartPtr m_fragmentReadTexMipmap;
ShaderPartPtr m_fragmentCallN64Depth; ShaderPartPtr m_fragmentCallN64Depth;
@ -87,6 +90,7 @@ namespace glsl {
ShaderPartPtr m_shaderReadtexCopyMode; ShaderPartPtr m_shaderReadtexCopyMode;
ShaderPartPtr m_shaderN64DepthCompare; ShaderPartPtr m_shaderN64DepthCompare;
ShaderPartPtr m_shaderN64DepthRender; ShaderPartPtr m_shaderN64DepthRender;
ShaderPartPtr m_shaderClampWrapMirror;
std::unique_ptr<CombinerProgramUniformFactory> m_uniformFactory; std::unique_ptr<CombinerProgramUniformFactory> m_uniformFactory;

View File

@ -815,9 +815,9 @@ public:
{ {
TextureCache & cache = textureCache(); TextureCache & cache = textureCache();
if (m_useT0 && cache.current[0] != NULL) if (m_useT0 && cache.current[0] != NULL)
uTextureSize[0].set((float)cache.current[0]->realWidth, (float)cache.current[0]->realHeight, _force); uTextureSize[0].set((float)cache.current[0]->width, (float)cache.current[0]->height, _force);
if (m_useT1 && cache.current[1] != NULL) if (m_useT1 && cache.current[1] != NULL)
uTextureSize[1].set((float)cache.current[1]->realWidth, (float)cache.current[1]->realHeight, _force); uTextureSize[1].set((float)cache.current[1]->width, (float)cache.current[1]->height, _force);
} }
private: private:
@ -853,35 +853,37 @@ public:
if (!m_useTile[t]) if (!m_useTile[t])
continue; continue;
if (gSP.textureTile[t] != nullptr) { gDPTile * pTile = gSP.textureTile[t];
if (gSP.textureTile[t]->textureMode == TEXTUREMODE_BGIMAGE || gSP.textureTile[t]->textureMode == TEXTUREMODE_FRAMEBUFFER_BG) if (pTile != nullptr) {
if (pTile->textureMode == TEXTUREMODE_BGIMAGE || pTile->textureMode == TEXTUREMODE_FRAMEBUFFER_BG)
uTexOffset[t].set(0.0f, 0.0f, _force); uTexOffset[t].set(0.0f, 0.0f, _force);
else { else {
float fuls = gSP.textureTile[t]->fuls; float fuls = pTile->fuls;
float fult = gSP.textureTile[t]->fult; float fult = pTile->fult;
if (gSP.textureTile[t]->frameBufferAddress > 0) { if (pTile->frameBufferAddress > 0) {
FrameBuffer * pBuffer = frameBufferList().getBuffer(gSP.textureTile[t]->frameBufferAddress); FrameBuffer * pBuffer = frameBufferList().getBuffer(pTile->frameBufferAddress);
if (pBuffer != nullptr) { if (pBuffer != nullptr) {
if (gSP.textureTile[t]->masks > 0 && gSP.textureTile[t]->clamps == 0) if (pTile->masks > 0 && pTile->clamps == 0)
fuls = float(gSP.textureTile[t]->uls % (1 << gSP.textureTile[t]->masks)); fuls = float(pTile->uls % (1 << pTile->masks));
if (gSP.textureTile[t]->maskt > 0 && gSP.textureTile[t]->clampt == 0) if (pTile->maskt > 0 && pTile->clampt == 0)
fult = float(gSP.textureTile[t]->ult % (1 << gSP.textureTile[t]->maskt)); fult = float(pTile->ult % (1 << pTile->maskt));
} else { } else {
gSP.textureTile[t]->frameBufferAddress = 0; pTile->frameBufferAddress = 0;
} }
} }
uTexOffset[t].set(fuls, fult, _force); uTexOffset[t].set(fuls, fult, _force);
} }
} }
if (cache.current[t] != nullptr) { CachedTexture *_pTexture = cache.current[t];
if (_pTexture != nullptr) {
f32 shiftScaleS = 1.0f; f32 shiftScaleS = 1.0f;
f32 shiftScaleT = 1.0f; f32 shiftScaleT = 1.0f;
getTextureShiftScale(t, cache, shiftScaleS, shiftScaleT); getTextureShiftScale(t, cache, shiftScaleS, shiftScaleT);
uCacheShiftScale[t].set(shiftScaleS, shiftScaleT, _force); uCacheShiftScale[t].set(shiftScaleS, shiftScaleT, _force);
uCacheScale[t].set(cache.current[t]->scaleS, cache.current[t]->scaleT, _force); uCacheScale[t].set(_pTexture->scaleS, _pTexture->scaleT, _force);
uCacheOffset[t].set(cache.current[t]->offsetS, cache.current[t]->offsetT, _force); uCacheOffset[t].set(_pTexture->offsetS, _pTexture->offsetT, _force);
nFB[t] = cache.current[t]->frameBufferTexture; nFB[t] = _pTexture->frameBufferTexture;
} }
} }
@ -899,6 +901,107 @@ private:
iv2Uniform uCacheFrameBuffer; iv2Uniform uCacheFrameBuffer;
}; };
class UClampWrapMirrorTex : public UniformGroup
{
public:
UClampWrapMirrorTex(GLuint _program, bool _useT0, bool _useT1)
{
m_useTile[0] = _useT0;
m_useTile[1] = _useT1;
LocateUniform(uTexClamp0);
LocateUniform(uTexClamp1);
LocateUniform(uTexWrap0);
LocateUniform(uTexWrap1);
LocateUniform(uTexMirror0);
LocateUniform(uTexMirror1);
LocateUniform(uTexScale0);
LocateUniform(uTexScale1);
}
void update(bool _force) override
{
std::array<f32, 4> aTexClamp[2] = { { -10000.0f, -10000.0f, 10000.0f, 10000.0f },
{ -10000.0f, -10000.0f, 10000.0f, 10000.0f } };
std::array<f32, 2> aTexWrap[2] = { { 10000.0f, 10000.0f }, { 10000.0f, 10000.0f } };
std::array<f32, 2> aTexMirror[2] = { { 0.0f, 0.0f}, { 0.0f, 0.0f } };
std::array<f32, 2> aTexScale[2] = { { 1.0f, 1.0f },{ 1.0f, 1.0f } };
TextureCache & cache = textureCache();
for (u32 t = 0; t < 2; ++t) {
if (!m_useTile[t])
continue;
const gDPTile * pTile = gSP.textureTile[t];
CachedTexture * pTexture = cache.current[t];
if (pTile == nullptr || pTexture == nullptr)
continue;
if (gDP.otherMode.cycleType != G_CYC_COPY) {
if (pTexture->clampS) {
aTexClamp[t][0] = 0.0f; // S lower bound
if (pTexture->frameBufferTexture != CachedTexture::fbNone)
aTexClamp[t][2] = 1.0f;
else {
u32 tileWidth = ((pTile->lrs - pTile->uls) & 0x03FF) + 1;
if (pTile->size > pTexture->size)
tileWidth <<= pTile->size - pTexture->size;
// aTexClamp[t][2] = f32(tileWidth) / (pTexture->mirrorS ? f32(pTexture->width) : f32(pTexture->clampWidth)); // S upper bound
aTexClamp[t][2] = f32(tileWidth) / f32(pTexture->width); // S upper bound
}
}
if (pTexture->clampT) {
aTexClamp[t][1] = 0.0f; // T lower bound
if (pTexture->frameBufferTexture != CachedTexture::fbNone)
aTexClamp[t][3] = 1.0f;
else {
const u32 tileHeight = ((pTile->lrt - pTile->ult) & 0x03FF) + 1;
// aTexClamp[t][3] = f32(tileHeight) / (pTexture->mirrorT ? f32(pTexture->height) : f32(pTexture->clampHeight)); // T upper bound
aTexClamp[t][3] = f32(tileHeight) / f32(pTexture->height); // T upper bound
}
}
}
if (pTexture->maskS) {
u32 wrapWidth = 1 << pTile->originalMaskS;
u32 pow2Width = pow2(pTexture->width);
aTexWrap[t][0] = f32(wrapWidth) / f32(pow2Width);
aTexScale[t][0] = 1.0f / (1.0f - f32(pow2Width - pTexture->width) / f32(pow2Width));
}
if (pTexture->maskT) {
u32 wrapHeight = 1 << pTile->originalMaskT;
u32 pow2Height = pow2(pTexture->height);
aTexWrap[t][1] = f32(wrapHeight) / f32(pow2Height);
aTexScale[t][1] = 1.0f / (1.0f - f32(pow2Height - pTexture->height) / f32(pow2Height));
}
if (pTexture->mirrorS) {
aTexMirror[t][0] = 1.0f;
aTexWrap[t][0] *= 2.0f;
}
if (pTexture->mirrorT) {
aTexMirror[t][1] = 1.0f;
aTexWrap[t][1] *= 2.0f;
}
}
uTexClamp0.set(aTexClamp[0].data(), _force);
uTexClamp1.set(aTexClamp[1].data(), _force);
uTexWrap0.set(aTexWrap[0][0], aTexWrap[0][1], _force);
uTexWrap1.set(aTexWrap[1][0], aTexWrap[1][1], _force);
uTexMirror0.set(aTexMirror[0][0], aTexMirror[0][1], _force);
uTexMirror1.set(aTexMirror[1][0], aTexMirror[1][1], _force);
uTexScale0.set(aTexScale[0][0], aTexScale[0][1], _force);
uTexScale1.set(aTexScale[1][0], aTexScale[1][1], _force);
}
private:
bool m_useTile[2];
fv4Uniform uTexClamp0;
fv4Uniform uTexClamp1;
fv2Uniform uTexWrap0;
fv2Uniform uTexWrap1;
fv2Uniform uTexMirror0;
fv2Uniform uTexMirror1;
fv2Uniform uTexScale0;
fv2Uniform uTexScale1;
};
class ULights : public UniformGroup class ULights : public UniformGroup
{ {
@ -966,6 +1069,8 @@ void CombinerProgramUniformFactory::buildUniforms(GLuint _program,
if (!_key.isRectKey()) if (!_key.isRectKey())
_uniforms.emplace_back(new UTextureParams(_program, _inputs.usesTile(0), _inputs.usesTile(1))); _uniforms.emplace_back(new UTextureParams(_program, _inputs.usesTile(0), _inputs.usesTile(1)));
_uniforms.emplace_back(new UClampWrapMirrorTex(_program, _inputs.usesTile(0), _inputs.usesTile(1)));
} }
_uniforms.emplace_back(new UFog(_program)); _uniforms.emplace_back(new UFog(_program));

View File

@ -20,7 +20,7 @@ namespace glsl {
bool _saveCombinerKeys(const graphics::Combiners & _combiners) const; bool _saveCombinerKeys(const graphics::Combiners & _combiners) const;
bool _loadFromCombinerKeys(graphics::Combiners & _combiners); bool _loadFromCombinerKeys(graphics::Combiners & _combiners);
const u32 m_formatVersion = 0x26U; const u32 m_formatVersion = 0x28U;
const u32 m_keysFormatVersion = 0x04; const u32 m_keysFormatVersion = 0x04;
const opengl::GLInfo & m_glinfo; const opengl::GLInfo & m_glinfo;
opengl::CachedUseProgram * m_useProgram; opengl::CachedUseProgram * m_useProgram;

View File

@ -539,9 +539,9 @@ namespace glsl {
FXAAShaderBase::activate(); FXAAShaderBase::activate();
FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN); FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN);
if (pBuffer != nullptr && pBuffer->m_pTexture != nullptr && if (pBuffer != nullptr && pBuffer->m_pTexture != nullptr &&
(m_width != pBuffer->m_pTexture->realWidth || m_height != pBuffer->m_pTexture->realHeight)) { (m_width != pBuffer->m_pTexture->width || m_height != pBuffer->m_pTexture->height)) {
m_width = pBuffer->m_pTexture->realWidth; m_width = pBuffer->m_pTexture->width;
m_height = pBuffer->m_pTexture->realHeight; m_height = pBuffer->m_pTexture->height;
glUniform2f(m_textureSizeLoc, GLfloat(m_width), GLfloat(m_height)); glUniform2f(m_textureSizeLoc, GLfloat(m_width), GLfloat(m_height));
} }
} }

View File

@ -54,7 +54,7 @@ const u8 * ColorBufferReaderWithBufferStorage::_readPixels(const ReadColorBuffer
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex])); m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex]));
glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, nullptr); glReadPixels(_params.x0, _params.y0, m_pTexture->width, _params.height, format, type, nullptr);
if (!_params.sync) { if (!_params.sync) {
m_curIndex = (m_curIndex + 1) % m_numPBO; m_curIndex = (m_curIndex + 1) % m_numPBO;
@ -63,7 +63,7 @@ const u8 * ColorBufferReaderWithBufferStorage::_readPixels(const ReadColorBuffer
} }
_heightOffset = 0; _heightOffset = 0;
_stride = m_pTexture->realWidth; _stride = m_pTexture->width;
return reinterpret_cast<u8*>(m_PBOData[m_curIndex]); return reinterpret_cast<u8*>(m_PBOData[m_curIndex]);
} }

View File

@ -51,7 +51,7 @@ const u8 * ColorBufferReaderWithPixelBuffer::_readPixels(const ReadColorBufferPa
GLenum type = GLenum(_params.colorType); GLenum type = GLenum(_params.colorType);
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex])); m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex]));
glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, 0); glReadPixels(_params.x0, _params.y0, m_pTexture->width, _params.height, format, type, 0);
// If Sync, read pixels from the buffer, copy them to RDRAM. // If Sync, read pixels from the buffer, copy them to RDRAM.
// If not Sync, read pixels from the buffer, copy pixels from the previous buffer to RDRAM. // If not Sync, read pixels from the buffer, copy pixels from the previous buffer to RDRAM.
if (!_params.sync) { if (!_params.sync) {
@ -60,10 +60,10 @@ const u8 * ColorBufferReaderWithPixelBuffer::_readPixels(const ReadColorBufferPa
} }
_heightOffset = 0; _heightOffset = 0;
_stride = m_pTexture->realWidth; _stride = m_pTexture->width;
return reinterpret_cast<u8*>(glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, return reinterpret_cast<u8*>(glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0,
m_pTexture->realWidth * _params.height * _params.colorFormatBytes, GL_MAP_READ_BIT)); m_pTexture->width * _params.height * _params.colorFormatBytes, GL_MAP_READ_BIT));
} }
void ColorBufferReaderWithPixelBuffer::cleanUp() void ColorBufferReaderWithPixelBuffer::cleanUp()

View File

@ -19,10 +19,10 @@ const u8 * ColorBufferReaderWithReadPixels::_readPixels(const ReadColorBufferPar
// No async pixel buffer copies are supported in this class, this is a last resort fallback // No async pixel buffer copies are supported in this class, this is a last resort fallback
u8* gpuData = m_pixelData.data(); u8* gpuData = m_pixelData.data();
glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, gpuData); glReadPixels(_params.x0, _params.y0, m_pTexture->width, _params.height, format, type, gpuData);
_heightOffset = 0; _heightOffset = 0;
_stride = m_pTexture->realWidth; _stride = m_pTexture->width;
return gpuData; return gpuData;
} }

View File

@ -82,15 +82,15 @@ void DisplayWindowWindows::_saveBufferContent(graphics::ObjectHandle _fbo, Cache
GLint oldMode; GLint oldMode;
glGetIntegerv(GL_READ_BUFFER, &oldMode); glGetIntegerv(GL_READ_BUFFER, &oldMode);
gfxContext.bindFramebuffer(graphics::bufferTarget::READ_FRAMEBUFFER, _fbo); gfxContext.bindFramebuffer(graphics::bufferTarget::READ_FRAMEBUFFER, _fbo);
pixelData = (unsigned char*)malloc(_pTexture->realWidth * _pTexture->realHeight * 3); pixelData = (unsigned char*)malloc(_pTexture->width * _pTexture->height * 3);
glReadPixels(0, 0, _pTexture->realWidth, _pTexture->realHeight, GL_RGB, GL_UNSIGNED_BYTE, pixelData); glReadPixels(0, 0, _pTexture->width, _pTexture->height, GL_RGB, GL_UNSIGNED_BYTE, pixelData);
if (graphics::BufferAttachmentParam(oldMode) == graphics::bufferAttachment::COLOR_ATTACHMENT0) { if (graphics::BufferAttachmentParam(oldMode) == graphics::bufferAttachment::COLOR_ATTACHMENT0) {
FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent(); FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent();
if (pCurrentBuffer != nullptr) if (pCurrentBuffer != nullptr)
gfxContext.bindFramebuffer(graphics::bufferTarget::READ_FRAMEBUFFER, pCurrentBuffer->m_FBO); gfxContext.bindFramebuffer(graphics::bufferTarget::READ_FRAMEBUFFER, pCurrentBuffer->m_FBO);
} }
glReadBuffer(oldMode); glReadBuffer(oldMode);
SaveScreenshot(m_strScreenDirectory, RSP.romname, _pTexture->realWidth, _pTexture->realHeight, pixelData); SaveScreenshot(m_strScreenDirectory, RSP.romname, _pTexture->width, _pTexture->height, pixelData);
free(pixelData); free(pixelData);
} }

View File

@ -122,17 +122,17 @@ void NoiseTexture::init()
m_pTexture[i]->maskT = 0; m_pTexture[i]->maskT = 0;
m_pTexture[i]->mirrorS = 0; m_pTexture[i]->mirrorS = 0;
m_pTexture[i]->mirrorT = 0; m_pTexture[i]->mirrorT = 0;
m_pTexture[i]->realWidth = NOISE_TEX_WIDTH; m_pTexture[i]->width = NOISE_TEX_WIDTH;
m_pTexture[i]->realHeight = NOISE_TEX_HEIGHT; m_pTexture[i]->height = NOISE_TEX_HEIGHT;
m_pTexture[i]->textureBytes = m_pTexture[i]->realWidth * m_pTexture[i]->realHeight; m_pTexture[i]->textureBytes = m_pTexture[i]->width * m_pTexture[i]->height;
const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats(); const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats();
{ {
Context::InitTextureParams params; Context::InitTextureParams params;
params.handle = m_pTexture[i]->name; params.handle = m_pTexture[i]->name;
params.textureUnitIndex = textureIndices::NoiseTex; params.textureUnitIndex = textureIndices::NoiseTex;
params.width = m_pTexture[i]->realWidth; params.width = m_pTexture[i]->width;
params.height = m_pTexture[i]->realHeight; params.height = m_pTexture[i]->height;
params.internalFormat = fbTexFormats.noiseInternalFormat; params.internalFormat = fbTexFormats.noiseInternalFormat;
params.format = fbTexFormats.noiseFormat; params.format = fbTexFormats.noiseFormat;
params.dataType = fbTexFormats.noiseType; params.dataType = fbTexFormats.noiseType;

View File

@ -35,14 +35,14 @@ void PaletteTexture::init()
m_pTexture->maskT = 0; m_pTexture->maskT = 0;
m_pTexture->mirrorS = 0; m_pTexture->mirrorS = 0;
m_pTexture->mirrorT = 0; m_pTexture->mirrorT = 0;
m_pTexture->realWidth = 256; m_pTexture->width = 256;
m_pTexture->realHeight = 1; m_pTexture->height = 1;
m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormats.lutFormatBytes; m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormats.lutFormatBytes;
Context::InitTextureParams initParams; Context::InitTextureParams initParams;
initParams.handle = m_pTexture->name; initParams.handle = m_pTexture->name;
initParams.width = m_pTexture->realWidth; initParams.width = m_pTexture->width;
initParams.height = m_pTexture->realHeight; initParams.height = m_pTexture->height;
initParams.internalFormat = fbTexFormats.lutInternalFormat; initParams.internalFormat = fbTexFormats.lutInternalFormat;
initParams.format = fbTexFormats.lutFormat; initParams.format = fbTexFormats.lutFormat;
initParams.dataType = fbTexFormats.lutType; initParams.dataType = fbTexFormats.lutType;
@ -93,8 +93,8 @@ void PaletteTexture::update()
Context::UpdateTextureDataParams params; Context::UpdateTextureDataParams params;
params.handle = m_pTexture->name; params.handle = m_pTexture->name;
params.textureUnitIndex = textureIndices::PaletteTex; params.textureUnitIndex = textureIndices::PaletteTex;
params.width = m_pTexture->realWidth; params.width = m_pTexture->width;
params.height = m_pTexture->realHeight; params.height = m_pTexture->height;
params.format = fbTexFormats.lutFormat; params.format = fbTexFormats.lutFormat;
params.internalFormat = fbTexFormats.lutInternalFormat; params.internalFormat = fbTexFormats.lutInternalFormat;
params.dataType = fbTexFormats.lutType; params.dataType = fbTexFormats.lutType;

View File

@ -33,14 +33,14 @@ void PostProcessor::_createResultBuffer(const FrameBuffer * _pMainBuffer)
pTexture->maskT = 0; pTexture->maskT = 0;
pTexture->mirrorS = 0; pTexture->mirrorS = 0;
pTexture->mirrorT = 0; pTexture->mirrorT = 0;
pTexture->realWidth = pMainTexture->realWidth; pTexture->width = pMainTexture->width;
pTexture->realHeight = pMainTexture->realHeight; pTexture->height = pMainTexture->height;
pTexture->textureBytes = pTexture->realWidth * pTexture->realHeight * 4; pTexture->textureBytes = pTexture->width * pTexture->height * 4;
Context::InitTextureParams initParams; Context::InitTextureParams initParams;
initParams.handle = pTexture->name; initParams.handle = pTexture->name;
initParams.width = pTexture->realWidth; initParams.width = pTexture->width;
initParams.height = pTexture->realHeight; initParams.height = pTexture->height;
initParams.internalFormat = gfxContext.convertInternalTextureFormat(u32(internalcolorFormat::RGBA8)); initParams.internalFormat = gfxContext.convertInternalTextureFormat(u32(internalcolorFormat::RGBA8));
initParams.format = colorFormat::RGBA; initParams.format = colorFormat::RGBA;
initParams.dataType = datatype::UNSIGNED_BYTE; initParams.dataType = datatype::UNSIGNED_BYTE;
@ -131,16 +131,16 @@ FrameBuffer * PostProcessor::_doPostProcessing(FrameBuffer * _pBuffer, graphics:
GraphicsDrawer::CopyRectParams copyParams; GraphicsDrawer::CopyRectParams copyParams;
copyParams.srcX0 = 0; copyParams.srcX0 = 0;
copyParams.srcY0 = 0; copyParams.srcY0 = 0;
copyParams.srcX1 = m_pTextureOriginal->realWidth; copyParams.srcX1 = m_pTextureOriginal->width;
copyParams.srcY1 = m_pTextureOriginal->realHeight; copyParams.srcY1 = m_pTextureOriginal->height;
copyParams.srcWidth = m_pTextureOriginal->realWidth; copyParams.srcWidth = m_pTextureOriginal->width;
copyParams.srcHeight = m_pTextureOriginal->realHeight; copyParams.srcHeight = m_pTextureOriginal->height;
copyParams.dstX0 = 0; copyParams.dstX0 = 0;
copyParams.dstY0 = 0; copyParams.dstY0 = 0;
copyParams.dstX1 = pDstTex->realWidth; copyParams.dstX1 = pDstTex->width;
copyParams.dstY1 = pDstTex->realHeight; copyParams.dstY1 = pDstTex->height;
copyParams.dstWidth = pDstTex->realWidth; copyParams.dstWidth = pDstTex->width;
copyParams.dstHeight = pDstTex->realHeight; copyParams.dstHeight = pDstTex->height;
copyParams.tex[0] = m_pTextureOriginal; copyParams.tex[0] = m_pTextureOriginal;
copyParams.filter = textureParameters::FILTER_NEAREST; copyParams.filter = textureParameters::FILTER_NEAREST;
copyParams.combiner = _pShader; copyParams.combiner = _pShader;

View File

@ -50,17 +50,17 @@ void TexrectDrawer::init()
m_pTexture->maskT = 0; m_pTexture->maskT = 0;
m_pTexture->mirrorS = 0; m_pTexture->mirrorS = 0;
m_pTexture->mirrorT = 0; m_pTexture->mirrorT = 0;
m_pTexture->realWidth = 640; m_pTexture->width = 640;
m_pTexture->realHeight = 580; m_pTexture->height = 580;
m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormats.colorFormatBytes; m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormats.colorFormatBytes;
m_stepX = 2.0f / 640.0f; m_stepX = 2.0f / 640.0f;
m_stepY = 2.0f / 580.0f; m_stepY = 2.0f / 580.0f;
Context::InitTextureParams initParams; Context::InitTextureParams initParams;
initParams.handle = m_pTexture->name; initParams.handle = m_pTexture->name;
initParams.textureUnitIndex = textureIndices::Tex[0]; initParams.textureUnitIndex = textureIndices::Tex[0];
initParams.width = m_pTexture->realWidth; initParams.width = m_pTexture->width;
initParams.height = m_pTexture->realHeight; initParams.height = m_pTexture->height;
initParams.internalFormat = fbTexFormats.colorInternalFormat; initParams.internalFormat = fbTexFormats.colorInternalFormat;
initParams.format = fbTexFormats.colorFormat; initParams.format = fbTexFormats.colorFormat;
initParams.dataType = fbTexFormats.colorType; initParams.dataType = fbTexFormats.colorType;
@ -89,7 +89,7 @@ void TexrectDrawer::init()
m_programTex.reset(gfxContext.createTexrectDrawerDrawShader()); m_programTex.reset(gfxContext.createTexrectDrawerDrawShader());
m_programClear.reset(gfxContext.createTexrectDrawerClearShader()); m_programClear.reset(gfxContext.createTexrectDrawerClearShader());
m_programTex->setTextureSize(m_pTexture->realWidth, m_pTexture->realHeight); m_programTex->setTextureSize(m_pTexture->width, m_pTexture->height);
m_vecRectCoords.reserve(256); m_vecRectCoords.reserve(256);
} }
@ -378,10 +378,10 @@ bool TexrectDrawer::draw()
scaleX *= 2.0f; scaleX *= 2.0f;
scaleY *= 2.0f; scaleY *= 2.0f;
const float s0 = (m_ulx + 1.0f) / scaleX / (float)m_pTexture->realWidth + 0.5f / (float)m_pTexture->realWidth; const float s0 = (m_ulx + 1.0f) / scaleX / (float)m_pTexture->width + 0.5f / (float)m_pTexture->width;
const float t0 = (m_lry + 1.0f) / scaleY / (float)m_pTexture->realHeight;// +0.5f / (float)m_pTexture->realHeight; const float t0 = (m_lry + 1.0f) / scaleY / (float)m_pTexture->height;// +0.5f / (float)m_pTexture->height;
const float s1 = (m_lrx + 1.0f) / scaleX / (float)m_pTexture->realWidth; const float s1 = (m_lrx + 1.0f) / scaleX / (float)m_pTexture->width;
const float t1 = (m_uly + 1.0f) / scaleY / (float)m_pTexture->realHeight; const float t1 = (m_uly + 1.0f) / scaleY / (float)m_pTexture->height;
const float W = 1.0f; const float W = 1.0f;
drawer._updateScreenCoordsViewport(m_pBuffer); drawer._updateScreenCoordsViewport(m_pBuffer);

View File

@ -108,9 +108,9 @@ struct Atlas {
m_pTexture->maskT = 0; m_pTexture->maskT = 0;
m_pTexture->mirrorS = 0; m_pTexture->mirrorS = 0;
m_pTexture->mirrorT = 0; m_pTexture->mirrorT = 0;
m_pTexture->realWidth = w; m_pTexture->width = w;
m_pTexture->realHeight = h; m_pTexture->height = h;
m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormats.noiseFormatBytes; m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormats.noiseFormatBytes;
Context::InitTextureParams initParams; Context::InitTextureParams initParams;
initParams.handle = m_pTexture->name; initParams.handle = m_pTexture->name;

View File

@ -214,28 +214,10 @@ inline u32 GetRGBA8888_RGBA4444( u64 *src, u16 x, u16 i, u8 palette )
return RGBA8888_RGBA4444(((u32*)src)[x^i]); return RGBA8888_RGBA4444(((u32*)src)[x^i]);
} }
#if 0
u32 YUV_RGBA8888(u8 y, u8 u, u8 v)
{
s32 r = (s32)(y + (1.370705f * (v - 128)));
s32 g = (s32)((y - (0.698001f * (v - 128)) - (0.337633f * (u - 128))));
s32 b = (s32)(y + (1.732446f * (u - 128)));
//clipping the result
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
if (r < 0) r = 0;
if (g < 0) g = 0;
if (b < 0) b = 0;
return (0xff << 24) | (b << 16) | (g << 8) | r;
}
#else
inline u32 YUV_RGBA8888(u8 y, u8 u, u8 v) inline u32 YUV_RGBA8888(u8 y, u8 u, u8 v)
{ {
return (0xff << 24) | (y << 16) | (v << 8) | u; return (0xff << 24) | (y << 16) | (v << 8) | u;
} }
#endif
inline void GetYUV_RGBA8888(u64 * src, u32 * dst, u16 x) inline void GetYUV_RGBA8888(u64 * src, u32 * dst, u16 x)
{ {
@ -460,8 +442,6 @@ void TextureCache::_initDummyTexture(CachedTexture * _pDummy)
_pDummy->frameBufferTexture = CachedTexture::fbNone; _pDummy->frameBufferTexture = CachedTexture::fbNone;
_pDummy->width = 2; _pDummy->width = 2;
_pDummy->height = 2; _pDummy->height = 2;
_pDummy->realWidth = 2;
_pDummy->realHeight = 2;
_pDummy->maskS = 0; _pDummy->maskS = 0;
_pDummy->maskT = 0; _pDummy->maskT = 0;
_pDummy->scaleS = 0.5f; _pDummy->scaleS = 0.5f;
@ -485,8 +465,8 @@ void TextureCache::init()
params.handle = m_pDummy->name; params.handle = m_pDummy->name;
params.mipMapLevel = 0; params.mipMapLevel = 0;
params.msaaLevel = 0; params.msaaLevel = 0;
params.width = m_pDummy->realWidth; params.width = m_pDummy->width;
params.height = m_pDummy->realHeight; params.height = m_pDummy->height;
params.format = colorFormat::RGBA; params.format = colorFormat::RGBA;
params.internalFormat = gfxContext.convertInternalTextureFormat(u32(internalcolorFormat::RGBA8)); params.internalFormat = gfxContext.convertInternalTextureFormat(u32(internalcolorFormat::RGBA8));
params.dataType = datatype::UNSIGNED_BYTE; params.dataType = datatype::UNSIGNED_BYTE;
@ -507,8 +487,8 @@ void TextureCache::init()
msParams.handle = m_pMSDummy->name; msParams.handle = m_pMSDummy->name;
msParams.mipMapLevel = 0; msParams.mipMapLevel = 0;
msParams.msaaLevel = config.video.multisampling; msParams.msaaLevel = config.video.multisampling;
msParams.width = m_pMSDummy->realWidth; msParams.width = m_pMSDummy->width;
msParams.height = m_pMSDummy->realHeight; msParams.height = m_pMSDummy->height;
msParams.format = colorFormat::RGBA; msParams.format = colorFormat::RGBA;
msParams.internalFormat = gfxContext.convertInternalTextureFormat(u32(internalcolorFormat::RGBA8)); msParams.internalFormat = gfxContext.convertInternalTextureFormat(u32(internalcolorFormat::RGBA8));
msParams.dataType = datatype::UNSIGNED_BYTE; msParams.dataType = datatype::UNSIGNED_BYTE;
@ -577,9 +557,11 @@ CachedTexture * TextureCache::addFrameBufferTexture(bool _multisample)
struct TileSizes struct TileSizes
{ {
u32 maskWidth, clampWidth, width, realWidth; u32 clampWidth = 0U;
u32 maskHeight, clampHeight, height, realHeight; u32 width = 0U;
u32 bytes; u32 clampHeight = 0U;
u32 height = 0U;
u32 bytes = 0U;
}; };
static static
@ -589,11 +571,9 @@ void _calcTileSizes(u32 _t, TileSizes & _sizes, gDPTile * _pLoadTile)
pTile->masks = pTile->originalMaskS; pTile->masks = pTile->originalMaskS;
pTile->maskt = pTile->originalMaskT; pTile->maskt = pTile->originalMaskT;
const TextureLoadParameters & loadParams =
ImageFormat::get().tlp[gDP.otherMode.textureLUT][pTile->size][pTile->format];
const u32 maxTexels = loadParams.maxTexels;
u32 tileWidth = ((pTile->lrs - pTile->uls) & 0x03FF) + 1; u32 tileWidth = ((pTile->lrs - pTile->uls) & 0x03FF) + 1;
u32 tileHeight = ((pTile->lrt - pTile->ult) & 0x03FF) + 1; u32 tileHeight = ((pTile->lrt - pTile->ult) & 0x03FF) + 1;
if (tileWidth == 1 && tileHeight == 1 && if (tileWidth == 1 && tileHeight == 1 &&
gDP.otherMode.cycleType == G_CYC_COPY && gDP.otherMode.cycleType == G_CYC_COPY &&
_pLoadTile != nullptr && _pLoadTile != nullptr &&
@ -606,22 +586,6 @@ void _calcTileSizes(u32 _t, TileSizes & _sizes, gDPTile * _pLoadTile)
tileHeight = lry - uly + 1; tileHeight = lry - uly + 1;
} }
const bool bUseLoadSizes = _pLoadTile != nullptr && _pLoadTile->loadType == LOADTYPE_TILE &&
(pTile->tmem == _pLoadTile->tmem);
u32 loadWidth = 0, loadHeight = 0;
if (bUseLoadSizes) {
loadWidth = ((_pLoadTile->lrs - _pLoadTile->uls) & 0x03FF) + 1;
loadHeight = ((_pLoadTile->lrt - _pLoadTile->ult) & 0x03FF) + 1;
}
const u32 lineWidth = pTile->line << loadParams.lineShift;
const u32 lineHeight = lineWidth != 0 ? min(maxTexels / lineWidth, tileHeight) : 0;
u32 maskWidth = 1 << pTile->masks;
u32 maskHeight = 1 << pTile->maskt;
u32 width, height;
const u32 tMemMask = gDP.otherMode.textureLUT == G_TT_NONE ? 0x1FF : 0xFF; const u32 tMemMask = gDP.otherMode.textureLUT == G_TT_NONE ? 0x1FF : 0xFF;
gDPLoadTileInfo &info = gDP.loadInfo[pTile->tmem & tMemMask]; gDPLoadTileInfo &info = gDP.loadInfo[pTile->tmem & tMemMask];
if (pTile->tmem == gDP.loadTile->tmem) { if (pTile->tmem == gDP.loadTile->tmem) {
@ -637,75 +601,44 @@ void _calcTileSizes(u32 _t, TileSizes & _sizes, gDPTile * _pLoadTile)
gDP.loadTile->loadWidth = gDP.loadTile->loadHeight = 0; gDP.loadTile->loadWidth = gDP.loadTile->loadHeight = 0;
} }
_sizes.bytes = info.bytes; _sizes.bytes = info.bytes;
u32 width = 0, height = 0;
if (info.loadType == LOADTYPE_TILE) { if (info.loadType == LOADTYPE_TILE) {
if (pTile->masks && ((maskWidth * maskHeight) <= maxTexels)) width = min(info.width, info.texWidth);
width = maskWidth; // Use mask width if set and valid if (info.size > pTile->size)
else { width <<= info.size - pTile->size;
width = info.width;
if (info.size > pTile->size) height = info.height;
width <<= info.size - pTile->size; if ((config.generalEmulation.hacks & hack_MK64) != 0 && (height % 2) != 0)
} height--;
if (pTile->maskt && ((maskWidth * maskHeight) <= maxTexels))
height = maskHeight;
else
height = info.height;
} else { } else {
if (pTile->masks && ((maskWidth * maskHeight) <= maxTexels)) int tile_width = pTile->lrs - pTile->uls + 1;
width = maskWidth; // Use mask width if set and valid int tile_height = pTile->lrt - pTile->ult + 1;
else if ((tileWidth * tileHeight) <= maxTexels)
width = tileWidth; // else use tile width if valid int mask_width = (pTile->masks == 0) ? (tile_width) : (1 << pTile->masks);
int mask_height = (pTile->maskt == 0) ? (tile_height) : (1 << pTile->maskt);
if ((pTile->clamps && tile_width <= 256))
width = min(mask_width, tile_width);
else else
width = lineWidth; // else use line-based width width = mask_width;
if (pTile->maskt && ((maskWidth * maskHeight) <= maxTexels)) if ((pTile->clampt && tile_height <= 256) || (mask_height > 256))
height = maskHeight; height = min(mask_height, tile_height);
else if ((tileWidth * tileHeight) <= maxTexels)
height = tileHeight;
else else
height = lineHeight; height = mask_height;
} }
_sizes.clampWidth = (pTile->clamps && gDP.otherMode.cycleType != G_CYC_COPY) ? tileWidth : width;
_sizes.clampHeight = (pTile->clampt && gDP.otherMode.cycleType != G_CYC_COPY) ? tileHeight : height;
// Make sure masking is valid
if (maskWidth > width) {
pTile->masks = powof(width);
maskWidth = 1 << pTile->masks;
}
if (maskHeight > height) {
pTile->maskt = powof(height);
maskHeight = 1 << pTile->maskt;
}
_sizes.maskWidth = maskWidth;
_sizes.maskHeight = maskHeight;
_sizes.width = width; _sizes.width = width;
_sizes.height = height; _sizes.height = height;
if (pTile->clamps != 0) _sizes.clampWidth = (pTile->clamps && gDP.otherMode.cycleType != G_CYC_COPY) ? tileWidth : width;
_sizes.realWidth = _sizes.clampWidth; _sizes.clampHeight = (pTile->clampt && gDP.otherMode.cycleType != G_CYC_COPY) ? tileHeight : height;
else if (pTile->masks != 0)
_sizes.realWidth = _sizes.maskWidth;
else
_sizes.realWidth = _sizes.width;
if (pTile->clampt != 0)
_sizes.realHeight = _sizes.clampHeight;
else if (pTile->maskt != 0)
_sizes.realHeight = _sizes.maskHeight;
else
_sizes.realHeight = _sizes.height;
if (gSP.texture.level > 0) {
_sizes.realWidth = pow2(_sizes.realWidth);
_sizes.realHeight = pow2(_sizes.realHeight);
}
} }
inline inline
void _updateCachedTexture(const GHQTexInfo & _info, CachedTexture *_pTexture, f32 _scale) void _updateCachedTexture(const GHQTexInfo & _info, CachedTexture *_pTexture, u16 widthOrg, u16 heightOrg)
{ {
_pTexture->textureBytes = _info.width * _info.height; _pTexture->textureBytes = _info.width * _info.height;
@ -714,20 +647,12 @@ void _updateCachedTexture(const GHQTexInfo & _info, CachedTexture *_pTexture, f3
format == internalcolorFormat::RGBA4 || format == internalcolorFormat::RGBA4 ||
format == internalcolorFormat::RGB5_A1) { format == internalcolorFormat::RGB5_A1) {
_pTexture->textureBytes <<= 1; _pTexture->textureBytes <<= 1;
} } else {
else {
_pTexture->textureBytes <<= 2; _pTexture->textureBytes <<= 2;
} }
if (_pTexture->realWidth == _pTexture->width * 2) _pTexture->scaleS = 1.0f / (_pTexture->maskS ? f32(pow2(widthOrg)) : f32(widthOrg));
_pTexture->clampS = 0; // force wrap or mirror s _pTexture->scaleT = 1.0f / (_pTexture->maskT ? f32(pow2(heightOrg)) : f32(heightOrg));
if (_pTexture->realHeight == _pTexture->height * 2)
_pTexture->clampT = 0; // force wrap or mirror t
_pTexture->realWidth = _info.width;
_pTexture->realHeight = _info.height;
_pTexture->scaleS = _scale / f32(_info.width);
_pTexture->scaleT = _scale / f32(_info.height);
_pTexture->bHDTexture = true; _pTexture->bHDTexture = true;
} }
@ -776,7 +701,7 @@ bool TextureCache::_loadHiresBackground(CachedTexture *_pTexture, u64 & _ricecrc
gfxContext.init2DTexture(params); gfxContext.init2DTexture(params);
assert(!gfxContext.isError()); assert(!gfxContext.isError());
_updateCachedTexture(ghqTexInfo, _pTexture, f32(ghqTexInfo.width) / f32(tile_width)); _updateCachedTexture(ghqTexInfo, _pTexture, tile_width, tile_height);
return true; return true;
} }
return false; return false;
@ -803,12 +728,12 @@ void TextureCache::_loadBackground(CachedTexture *pTexture)
const TextureLoadParameters & loadParams = const TextureLoadParameters & loadParams =
ImageFormat::get().tlp[pTexture->format == 2 ? G_TT_RGBA16 : G_TT_NONE][pTexture->size][pTexture->format]; ImageFormat::get().tlp[pTexture->format == 2 ? G_TT_RGBA16 : G_TT_NONE][pTexture->size][pTexture->format];
if (loadParams.autoFormat == internalcolorFormat::RGBA8) { if (loadParams.autoFormat == internalcolorFormat::RGBA8) {
pTexture->textureBytes = (pTexture->realWidth * pTexture->realHeight) << 2; pTexture->textureBytes = (pTexture->width * pTexture->height) << 2;
GetTexel = loadParams.Get32; GetTexel = loadParams.Get32;
glInternalFormat = loadParams.glInternalFormat32; glInternalFormat = loadParams.glInternalFormat32;
glType = loadParams.glType32; glType = loadParams.glType32;
} else { } else {
pTexture->textureBytes = (pTexture->realWidth * pTexture->realHeight) << 1; pTexture->textureBytes = (pTexture->width * pTexture->height) << 1;
GetTexel = loadParams.Get16; GetTexel = loadParams.Get16;
glInternalFormat = loadParams.glInternalFormat16; glInternalFormat = loadParams.glInternalFormat16;
glType = loadParams.glType16; glType = loadParams.glType16;
@ -831,12 +756,12 @@ void TextureCache::_loadBackground(CachedTexture *pTexture)
clampTClamp = pTexture->height - 1; clampTClamp = pTexture->height - 1;
j = 0; j = 0;
for (y = 0; y < pTexture->realHeight; y++) { for (y = 0; y < pTexture->height; y++) {
ty = min(y, (u32)clampTClamp); ty = min(y, (u32)clampTClamp);
pSrc = &pSwapped[bpl * ty]; pSrc = &pSwapped[bpl * ty];
for (x = 0; x < pTexture->realWidth; x++) { for (x = 0; x < pTexture->width; x++) {
tx = min(x, (u32)clampSClamp); tx = min(x, (u32)clampSClamp);
if (glInternalFormat == internalcolorFormat::RGBA8) if (glInternalFormat == internalcolorFormat::RGBA8)
@ -856,8 +781,8 @@ void TextureCache::_loadBackground(CachedTexture *pTexture)
if (m_toggleDumpTex && if (m_toggleDumpTex &&
config.textureFilter.txHiresEnable != 0 && config.textureFilter.txHiresEnable != 0 &&
config.textureFilter.txDump != 0) { config.textureFilter.txDump != 0) {
txfilter_dmptx((u8*)pDest, pTexture->realWidth, pTexture->realHeight, txfilter_dmptx((u8*)pDest, pTexture->width, pTexture->height,
pTexture->realWidth, (u16)u32(glInternalFormat), pTexture->width, (u16)u32(glInternalFormat),
(unsigned short)(pTexture->format << 8 | pTexture->size), (unsigned short)(pTexture->format << 8 | pTexture->size),
ricecrc); ricecrc);
} }
@ -867,7 +792,7 @@ void TextureCache::_loadBackground(CachedTexture *pTexture)
config.textureFilter.txFilterIgnoreBG == 0 && config.textureFilter.txFilterIgnoreBG == 0 &&
TFH.isInited()) { TFH.isInited()) {
GHQTexInfo ghqTexInfo; GHQTexInfo ghqTexInfo;
if (txfilter_filter((u8*)pDest, pTexture->realWidth, pTexture->realHeight, if (txfilter_filter((u8*)pDest, pTexture->width, pTexture->height,
(u16)u32(glInternalFormat), (uint64)pTexture->crc, &ghqTexInfo) != 0 && (u16)u32(glInternalFormat), (uint64)pTexture->crc, &ghqTexInfo) != 0 &&
ghqTexInfo.data != nullptr) { ghqTexInfo.data != nullptr) {
@ -888,19 +813,19 @@ void TextureCache::_loadBackground(CachedTexture *pTexture)
params.dataType = DatatypeParam(ghqTexInfo.pixel_type); params.dataType = DatatypeParam(ghqTexInfo.pixel_type);
params.data = ghqTexInfo.data; params.data = ghqTexInfo.data;
gfxContext.init2DTexture(params); gfxContext.init2DTexture(params);
_updateCachedTexture(ghqTexInfo, pTexture, f32(ghqTexInfo.width) / f32(pTexture->realWidth)); _updateCachedTexture(ghqTexInfo, pTexture, pTexture->width, pTexture->height);
bLoaded = true; bLoaded = true;
} }
} }
if (!bLoaded) { if (!bLoaded) {
if (pTexture->realWidth % 2 != 0 && glInternalFormat != internalcolorFormat::RGBA8) if (pTexture->width % 2 != 0 && glInternalFormat != internalcolorFormat::RGBA8)
gfxContext.setTextureUnpackAlignment(2); gfxContext.setTextureUnpackAlignment(2);
Context::InitTextureParams params; Context::InitTextureParams params;
params.handle = pTexture->name; params.handle = pTexture->name;
params.mipMapLevel = 0; params.mipMapLevel = 0;
params.msaaLevel = 0; params.msaaLevel = 0;
params.width = pTexture->realWidth; params.width = pTexture->width;
params.height = pTexture->realHeight; params.height = pTexture->height;
params.format = colorFormat::RGBA; params.format = colorFormat::RGBA;
params.internalFormat = gfxContext.convertInternalTextureFormat(u32(glInternalFormat)); params.internalFormat = gfxContext.convertInternalTextureFormat(u32(glInternalFormat));
params.dataType = glType; params.dataType = glType;
@ -995,7 +920,7 @@ bool TextureCache::_loadHiresTexture(u32 _tile, CachedTexture *_pTexture, u64 &
params.textureUnitIndex = textureIndices::Tex[_tile]; params.textureUnitIndex = textureIndices::Tex[_tile];
gfxContext.init2DTexture(params); gfxContext.init2DTexture(params);
assert(!gfxContext.isError()); assert(!gfxContext.isError());
_updateCachedTexture(ghqTexInfo, _pTexture, f32(ghqTexInfo.width) / f32(width)); _updateCachedTexture(ghqTexInfo, _pTexture, width, height);
return true; return true;
} }
@ -1007,7 +932,7 @@ void TextureCache::_loadDepthTexture(CachedTexture * _pTexture, u16* _pDest)
if (!config.generalEmulation.enableFragmentDepthWrite) if (!config.generalEmulation.enableFragmentDepthWrite)
return; return;
u32 size = _pTexture->realWidth * _pTexture->realHeight; u32 size = _pTexture->width * _pTexture->height;
std::vector<f32> pDestFloat(size); std::vector<f32> pDestFloat(size);
for (u32 i = 0; i < size; ++i) for (u32 i = 0; i < size; ++i)
pDestFloat[i] = _pDest[i] / 65535.0f; pDestFloat[i] = _pDest[i] / 65535.0f;
@ -1016,8 +941,8 @@ void TextureCache::_loadDepthTexture(CachedTexture * _pTexture, u16* _pDest)
params.handle = _pTexture->name; params.handle = _pTexture->name;
params.mipMapLevel = 0; params.mipMapLevel = 0;
params.msaaLevel = 0; params.msaaLevel = 0;
params.width = _pTexture->realWidth; params.width = _pTexture->width;
params.height = _pTexture->realHeight; params.height = _pTexture->height;
params.internalFormat = internalcolorFormat::R16F; params.internalFormat = internalcolorFormat::R16F;
params.format = colorFormat::RED; params.format = colorFormat::RED;
params.dataType = datatype::FLOAT; params.dataType = datatype::FLOAT;
@ -1034,29 +959,26 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex,
GetTexelFunc GetTexel, GetTexelFunc GetTexel,
u16* pLine) u16* pLine)
{ {
u16 mirrorSBit, maskSMask, clampSClamp; u16 maskSMask, clampSClamp;
u16 mirrorTBit, maskTMask, clampTClamp; u16 maskTMask, clampTClamp;
u16 x, y, tx, ty; u16 x, y, tx, ty;
u32 i, j; u32 i, j;
u64 *pSrc; u64 *pSrc;
if (tmptex.maskS > 0) { if (tmptex.maskS > 0) {
clampSClamp = tmptex.clampS ? tmptex.clampWidth - 1 : (tmptex.mirrorS ? (tmptex.width << 1) - 1 : tmptex.width - 1); clampSClamp = tmptex.clampS ? tmptex.clampWidth - 1 : (tmptex.mirrorS ? (tmptex.width << 1) - 1 : tmptex.width - 1);
maskSMask = (1 << tmptex.maskS) - 1; maskSMask = (1 << tmptex.maskS) - 1;
mirrorSBit = tmptex.mirrorS != 0 ? 1 << tmptex.maskS : 0;
} else { } else {
clampSClamp = tmptex.clampS ? tmptex.clampWidth - 1 : tmptex.width - 1; clampSClamp = tmptex.clampS ? tmptex.clampWidth - 1 : tmptex.width - 1;
maskSMask = 0xFFFF; maskSMask = 0xFFFF;
mirrorSBit = 0x0000;
} }
if (tmptex.maskT > 0) { if (tmptex.maskT > 0) {
clampTClamp = tmptex.clampT ? tmptex.clampHeight - 1 : (tmptex.mirrorT ? (tmptex.height << 1) - 1 : tmptex.height - 1); clampTClamp = tmptex.clampT ? tmptex.clampHeight - 1 : (tmptex.mirrorT ? (tmptex.height << 1) - 1 : tmptex.height - 1);
maskTMask = (1 << tmptex.maskT) - 1; maskTMask = (1 << tmptex.maskT) - 1;
mirrorTBit = tmptex.mirrorT != 0 ? 1 << tmptex.maskT : 0;
} else { } else {
clampTClamp = tmptex.clampT ? tmptex.clampHeight - 1 : tmptex.height - 1; clampTClamp = tmptex.clampT ? tmptex.clampHeight - 1 : tmptex.height - 1;
maskTMask = 0xFFFF; maskTMask = 0xFFFF;
mirrorTBit = 0x0000;
} }
if (tmptex.size == G_IM_SIZ_32b) { if (tmptex.size == G_IM_SIZ_32b) {
@ -1080,20 +1002,14 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex,
u16 gr, ab; u16 gr, ab;
j = 0; j = 0;
for (y = 0; y < tmptex.realHeight; ++y) { for (y = 0; y < tmptex.height; ++y) {
ty = min(y, clampTClamp) & maskTMask; ty = min(y, clampTClamp) & maskTMask;
if (y & mirrorTBit) {
ty ^= maskTMask;
}
u32 tline = tbase + line32 * ty; u32 tline = tbase + line32 * ty;
u32 xorval = (ty & 1) ? 3 : 1; u32 xorval = (ty & 1) ? 3 : 1;
for (x = 0; x < tmptex.realWidth; ++x) { for (x = 0; x < tmptex.width; ++x) {
tx = min(x, clampSClamp) & maskSMask; tx = min(x, clampSClamp) & maskSMask;
if (x & mirrorSBit) {
tx ^= maskSMask;
}
u32 taddr = ((tline + tx) ^ xorval) & 0x3ff; u32 taddr = ((tline + tx) ^ xorval) & 0x3ff;
gr = swapword(tmem16[taddr]); gr = swapword(tmem16[taddr]);
@ -1104,9 +1020,9 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex,
} else if (tmptex.format == G_IM_FMT_YUV) { } else if (tmptex.format == G_IM_FMT_YUV) {
j = 0; j = 0;
*pLine <<= 1; *pLine <<= 1;
for (y = 0; y < tmptex.realHeight; ++y) { for (y = 0; y < tmptex.height; ++y) {
pSrc = &TMEM[tmptex.tMem] + *pLine * y; pSrc = &TMEM[tmptex.tMem] + *pLine * y;
for (x = 0; x < tmptex.realWidth / 2; x++) { for (x = 0; x < tmptex.width / 2; x++) {
GetYUV_RGBA8888(pSrc, pDest + j, x); GetYUV_RGBA8888(pSrc, pDest + j, x);
j += 2; j += 2;
} }
@ -1114,22 +1030,15 @@ void TextureCache::_getTextureDestData(CachedTexture& tmptex,
} else { } else {
j = 0; j = 0;
const u32 tMemMask = gDP.otherMode.textureLUT == G_TT_NONE ? 0x1FF : 0xFF; const u32 tMemMask = gDP.otherMode.textureLUT == G_TT_NONE ? 0x1FF : 0xFF;
for (y = 0; y < tmptex.realHeight; ++y) { for (y = 0; y < tmptex.height; ++y) {
ty = min(y, clampTClamp) & maskTMask; ty = min(y, clampTClamp) & maskTMask;
if (y & mirrorTBit)
ty ^= maskTMask;
pSrc = &TMEM[(tmptex.tMem + *pLine * ty) & tMemMask]; pSrc = &TMEM[(tmptex.tMem + *pLine * ty) & tMemMask];
i = (ty & 1) << 1; i = (ty & 1) << 1;
for (x = 0; x < tmptex.realWidth; ++x) { for (x = 0; x < tmptex.width; ++x) {
tx = min(x, clampSClamp) & maskSMask; tx = min(x, clampSClamp) & maskSMask;
if (x & mirrorSBit) {
tx ^= maskSMask;
}
if (glInternalFormat == internalcolorFormat::RGBA8) { if (glInternalFormat == internalcolorFormat::RGBA8) {
pDest[j++] = GetTexel(pSrc, tx, i, tmptex.palette); pDest[j++] = GetTexel(pSrc, tx, i, tmptex.palette);
} else { } else {
@ -1158,13 +1067,13 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
ImageFormat::get().tlp[gDP.otherMode.textureLUT][_pTexture->size][_pTexture->format]; ImageFormat::get().tlp[gDP.otherMode.textureLUT][_pTexture->size][_pTexture->format];
if (loadParams.autoFormat == internalcolorFormat::RGBA8) { if (loadParams.autoFormat == internalcolorFormat::RGBA8) {
sizeShift = 2; sizeShift = 2;
_pTexture->textureBytes = (_pTexture->realWidth * _pTexture->realHeight) << sizeShift; _pTexture->textureBytes = (_pTexture->width * _pTexture->height) << sizeShift;
GetTexel = loadParams.Get32; GetTexel = loadParams.Get32;
glInternalFormat = loadParams.glInternalFormat32; glInternalFormat = loadParams.glInternalFormat32;
glType = loadParams.glType32; glType = loadParams.glType32;
} else { } else {
sizeShift = 1; sizeShift = 1;
_pTexture->textureBytes = (_pTexture->realWidth * _pTexture->realHeight) << sizeShift; _pTexture->textureBytes = (_pTexture->width * _pTexture->height) << sizeShift;
GetTexel = loadParams.Get16; GetTexel = loadParams.Get16;
glInternalFormat = loadParams.glInternalFormat16; glInternalFormat = loadParams.glInternalFormat16;
glType = loadParams.glType16; glType = loadParams.glType16;
@ -1205,8 +1114,8 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
if (m_toggleDumpTex && if (m_toggleDumpTex &&
config.textureFilter.txHiresEnable != 0 && config.textureFilter.txHiresEnable != 0 &&
config.textureFilter.txDump != 0) { config.textureFilter.txDump != 0) {
txfilter_dmptx((u8*)pDest, tmptex.realWidth, tmptex.realHeight, txfilter_dmptx((u8*)pDest, tmptex.width, tmptex.height,
tmptex.realWidth, (u16)u32(glInternalFormat), tmptex.width, (u16)u32(glInternalFormat),
(unsigned short)(_pTexture->format << 8 | _pTexture->size), (unsigned short)(_pTexture->format << 8 | _pTexture->size),
ricecrc); ricecrc);
} }
@ -1232,7 +1141,7 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
if (needEnhance) { if (needEnhance) {
GHQTexInfo ghqTexInfo; GHQTexInfo ghqTexInfo;
if (txfilter_filter((u8*)pDest, tmptex.realWidth, tmptex.realHeight, if (txfilter_filter((u8*)pDest, tmptex.width, tmptex.height,
(u16)u32(glInternalFormat), (uint64)_pTexture->crc, (u16)u32(glInternalFormat), (uint64)_pTexture->crc,
&ghqTexInfo) != 0 && ghqTexInfo.data != nullptr) { &ghqTexInfo) != 0 && ghqTexInfo.data != nullptr) {
if (ghqTexInfo.width % 2 != 0 && if (ghqTexInfo.width % 2 != 0 &&
@ -1252,12 +1161,12 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
params.dataType = DatatypeParam(ghqTexInfo.pixel_type); params.dataType = DatatypeParam(ghqTexInfo.pixel_type);
params.data = ghqTexInfo.data; params.data = ghqTexInfo.data;
gfxContext.init2DTexture(params); gfxContext.init2DTexture(params);
_updateCachedTexture(ghqTexInfo, _pTexture, f32(ghqTexInfo.width) / f32(tmptex.realWidth)); _updateCachedTexture(ghqTexInfo, _pTexture, tmptex.width, tmptex.height);
bLoaded = true; bLoaded = true;
} }
} }
if (!bLoaded) { if (!bLoaded) {
if (tmptex.realWidth % 2 != 0 && if (tmptex.width % 2 != 0 &&
glInternalFormat != internalcolorFormat::RGBA8 && glInternalFormat != internalcolorFormat::RGBA8 &&
m_curUnpackAlignment > 1) m_curUnpackAlignment > 1)
gfxContext.setTextureUnpackAlignment(2); gfxContext.setTextureUnpackAlignment(2);
@ -1267,8 +1176,8 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
params.mipMapLevel = mipLevel; params.mipMapLevel = mipLevel;
params.mipMapLevels = _pTexture->max_level + 1; params.mipMapLevels = _pTexture->max_level + 1;
params.msaaLevel = 0; params.msaaLevel = 0;
params.width = tmptex.realWidth; params.width = tmptex.width;
params.height = tmptex.realHeight; params.height = tmptex.height;
params.internalFormat = gfxContext.convertInternalTextureFormat(u32(glInternalFormat)); params.internalFormat = gfxContext.convertInternalTextureFormat(u32(glInternalFormat));
params.format = colorFormat::RGBA; params.format = colorFormat::RGBA;
params.dataType = glType; params.dataType = glType;
@ -1287,16 +1196,14 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
tmptex.maskT = mipTile.maskt; tmptex.maskT = mipTile.maskt;
TileSizes sizes; TileSizes sizes;
_calcTileSizes(tileMipLevel, sizes, nullptr); _calcTileSizes(tileMipLevel, sizes, nullptr);
tmptex.width = sizes.width;
tmptex.clampWidth = sizes.clampWidth; tmptex.clampWidth = sizes.clampWidth;
tmptex.height = sizes.height;
tmptex.clampHeight = sizes.clampHeight; tmptex.clampHeight = sizes.clampHeight;
// Insure mip-map levels size consistency. // Insure mip-map levels size consistency.
if (tmptex.realWidth > 1) if (tmptex.width > 1)
tmptex.realWidth >>= 1; tmptex.width >>= 1;
if (tmptex.realHeight > 1) if (tmptex.height > 1)
tmptex.realHeight >>= 1; tmptex.height >>= 1;
_pTexture->textureBytes += (tmptex.realWidth * tmptex.realHeight) << sizeShift; _pTexture->textureBytes += (tmptex.width * tmptex.height) << sizeShift;
} }
if (m_curUnpackAlignment > 1) if (m_curUnpackAlignment > 1)
gfxContext.setTextureUnpackAlignment(m_curUnpackAlignment); gfxContext.setTextureUnpackAlignment(m_curUnpackAlignment);
@ -1384,11 +1291,9 @@ void TextureCache::activateTexture(u32 _t, CachedTexture *_pTexture)
// Set clamping modes // Set clamping modes
params.wrapS = _pTexture->clampS ? textureParameters::WRAP_CLAMP_TO_EDGE : params.wrapS = _pTexture->clampS ? textureParameters::WRAP_CLAMP_TO_EDGE :
_pTexture->mirrorS ? textureParameters::WRAP_MIRRORED_REPEAT _pTexture->mirrorS ? textureParameters::WRAP_MIRRORED_REPEAT : textureParameters::WRAP_REPEAT;
: textureParameters::WRAP_REPEAT;
params.wrapT = _pTexture->clampT ? textureParameters::WRAP_CLAMP_TO_EDGE : params.wrapT = _pTexture->clampT ? textureParameters::WRAP_CLAMP_TO_EDGE :
_pTexture->mirrorT ? textureParameters::WRAP_MIRRORED_REPEAT _pTexture->mirrorT ? textureParameters::WRAP_MIRRORED_REPEAT : textureParameters::WRAP_REPEAT;
: textureParameters::WRAP_REPEAT;
if (dwnd().getDrawer().getDrawingState() == DrawingState::Triangle && config.texture.maxAnisotropyF > 0.0f) if (dwnd().getDrawer().getDrawingState() == DrawingState::Triangle && config.texture.maxAnisotropyF > 0.0f)
params.maxAnisotropy = Parameter(config.texture.maxAnisotropyF); params.maxAnisotropy = Parameter(config.texture.maxAnisotropyF);
@ -1479,11 +1384,8 @@ void TextureCache::_updateBackground()
pCurrent->tMem = 0; pCurrent->tMem = 0;
pCurrent->frameBufferTexture = CachedTexture::fbNone; pCurrent->frameBufferTexture = CachedTexture::fbNone;
pCurrent->realWidth = gSP.bgImage.width; pCurrent->scaleS = 1.0f / (f32)(pCurrent->width);
pCurrent->realHeight = gSP.bgImage.height; pCurrent->scaleT = 1.0f / (f32)(pCurrent->height);
pCurrent->scaleS = 1.0f / (f32)(pCurrent->realWidth);
pCurrent->scaleT = 1.0f / (f32)(pCurrent->realHeight);
pCurrent->shiftScaleS = 1.0f; pCurrent->shiftScaleS = 1.0f;
pCurrent->shiftScaleT = 1.0f; pCurrent->shiftScaleT = 1.0f;
@ -1574,8 +1476,8 @@ void TextureCache::update(u32 _t)
(pTile->size << 12) | (pTile->size << 12) |
(pTile->format << 14) | (pTile->format << 14) |
(gDP.otherMode.textureLUT << 17); (gDP.otherMode.textureLUT << 17);
params.width = sizes.realWidth; params.width = sizes.width;
params.height = sizes.realHeight; params.height = sizes.height;
const u32 crc = _calculateCRC(_t, params, sizes.bytes); const u32 crc = _calculateCRC(_t, params, sizes.bytes);
@ -1637,11 +1539,8 @@ void TextureCache::update(u32 _t)
pCurrent->tMem = pTile->tmem; pCurrent->tMem = pTile->tmem;
pCurrent->frameBufferTexture = CachedTexture::fbNone; pCurrent->frameBufferTexture = CachedTexture::fbNone;
pCurrent->realWidth = sizes.realWidth; pCurrent->scaleS = 1.0f / (pCurrent->maskS ? f32(pow2(pCurrent->width)) : f32(pCurrent->width));
pCurrent->realHeight = sizes.realHeight; pCurrent->scaleT = 1.0f / (pCurrent->maskT ? f32(pow2(pCurrent->height)) : f32(pCurrent->height));
pCurrent->scaleS = 1.0f / (f32)(pCurrent->realWidth);
pCurrent->scaleT = 1.0f / (f32)(pCurrent->realHeight);
pCurrent->offsetS = 0.5f; pCurrent->offsetS = 0.5f;
pCurrent->offsetT = 0.5f; pCurrent->offsetT = 0.5f;
@ -1673,3 +1572,22 @@ void getTextureShiftScale(u32 t, const TextureCache & cache, f32 & shiftScaleS,
else if (gSP.textureTile[t]->shiftt > 0) else if (gSP.textureTile[t]->shiftt > 0)
shiftScaleT /= (f32)(1 << gSP.textureTile[t]->shiftt); shiftScaleT /= (f32)(1 << gSP.textureTile[t]->shiftt);
} }
void getMirrorClamp(u32 _tile, const CachedTexture * _pTexture, MirrorClamp& aMirrorClamp)
{
const gDPTile * pTile = gSP.textureTile[_tile];
const u32 tileWidth = ((pTile->lrs - pTile->uls) & 0x03FF) + 1;
const u32 tileHeight = ((pTile->lrt - pTile->ult) & 0x03FF) + 1;
const bool mirrorClampS = _pTexture->mirrorS && _pTexture->clampS &&
tileWidth > _pTexture->width && tileWidth % _pTexture->width == 0;
const bool mirrorClampT = _pTexture->mirrorT && _pTexture->clampT &&
tileHeight > _pTexture->height && tileHeight % _pTexture->height == 0;
if (mirrorClampS) {
aMirrorClamp[0] = 0.0f;
aMirrorClamp[2] = f32(tileWidth / _pTexture->width);
}
if (mirrorClampT) {
aMirrorClamp[1] = 0.0f;
aMirrorClamp[3] = f32(tileHeight / _pTexture->height);
}
}

View File

@ -1,9 +1,10 @@
#ifndef TEXTURES_H #ifndef TEXTURES_H
#define TEXTURES_H #define TEXTURES_H
#include <array>
#include <list>
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
#include <list>
#include "CRC.h" #include "CRC.h"
#include "convert.h" #include "convert.h"
@ -31,7 +32,6 @@ struct CachedTexture
u32 palette; u32 palette;
u16 width, height; // N64 width and height u16 width, height; // N64 width and height
u16 clampWidth, clampHeight; // Size to clamp to u16 clampWidth, clampHeight; // Size to clamp to
u16 realWidth, realHeight; // Actual texture size
f32 scaleS, scaleT; // Scale to map to 0.0-1.0 f32 scaleS, scaleT; // Scale to map to 0.0-1.0
f32 shiftScaleS, shiftScaleT; // Scale to shift f32 shiftScaleS, shiftScaleT; // Scale to shift
u32 textureBytes; u32 textureBytes;
@ -109,6 +109,9 @@ private:
void getTextureShiftScale(u32 tile, const TextureCache & cache, f32 & shiftScaleS, f32 & shiftScaleT); void getTextureShiftScale(u32 tile, const TextureCache & cache, f32 & shiftScaleS, f32 & shiftScaleT);
using MirrorClamp = std::array<f32, 4>;
void getMirrorClamp(u32 _tile, const CachedTexture * _pTexture, MirrorClamp& aMirrorClamp);
inline TextureCache & textureCache() inline TextureCache & textureCache()
{ {
return TextureCache::get(); return TextureCache::get();

View File

@ -35,14 +35,14 @@ void ZlutTexture::init()
m_pTexture->maskT = 0; m_pTexture->maskT = 0;
m_pTexture->mirrorS = 0; m_pTexture->mirrorS = 0;
m_pTexture->mirrorT = 0; m_pTexture->mirrorT = 0;
m_pTexture->realWidth = 512; m_pTexture->width = 512;
m_pTexture->realHeight = 512; m_pTexture->height = 512;
m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * fbTexFormats.lutFormatBytes; m_pTexture->textureBytes = m_pTexture->width * m_pTexture->height * fbTexFormats.lutFormatBytes;
Context::InitTextureParams initParams; Context::InitTextureParams initParams;
initParams.handle = m_pTexture->name; initParams.handle = m_pTexture->name;
initParams.width = m_pTexture->realWidth; initParams.width = m_pTexture->width;
initParams.height = m_pTexture->realHeight; initParams.height = m_pTexture->height;
initParams.internalFormat = fbTexFormats.lutInternalFormat; initParams.internalFormat = fbTexFormats.lutInternalFormat;
initParams.format = fbTexFormats.lutFormat; initParams.format = fbTexFormats.lutFormat;
initParams.dataType = fbTexFormats.lutType; initParams.dataType = fbTexFormats.lutType;

View File

@ -637,6 +637,15 @@ void gDPLoadBlock(u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt)
gDP.loadTile->frameBufferAddress = 0; gDP.loadTile->frameBufferAddress = 0;
CheckForFrameBufferTexture(address, info.width, bytes); // Load data to TMEM even if FB texture is found. See comment to texturedRectDepthBufferCopy CheckForFrameBufferTexture(address, info.width, bytes); // Load data to TMEM even if FB texture is found. See comment to texturedRectDepthBufferCopy
const u32 texLowerBound = gDP.loadTile->tmem;
const u32 texUpperBound = gDP.loadTile->tmem + (bytes >> 3);
for (u32 i = 0; i < tile; ++i) {
if (gDP.tiles[i].tmem >= texLowerBound && gDP.tiles[i].tmem < texUpperBound) {
gDPLoadTileInfo &info = gDP.loadInfo[gDP.tiles[i].tmem];
info.loadType = LOADTYPE_BLOCK;
}
}
if (gDP.loadTile->size == G_IM_SIZ_32b) if (gDP.loadTile->size == G_IM_SIZ_32b)
gDPLoadBlock32(gDP.loadTile->uls, gDP.loadTile->lrs, dxt); gDPLoadBlock32(gDP.loadTile->uls, gDP.loadTile->lrs, dxt);
else if (gDP.loadTile->format == G_IM_FMT_YUV) else if (gDP.loadTile->format == G_IM_FMT_YUV)