SoftRasterizer: Texture deposterization and upscaling are now supported with this renderer.

This commit is contained in:
rogerman 2016-11-27 16:10:00 -08:00
parent 0a4635eb5b
commit a8c8a8665b
4 changed files with 198 additions and 11 deletions

View File

@ -55,6 +55,8 @@
#include "MMU.h"
#include "NDSSystem.h"
#include "utils/task.h"
#include "filter/filter.h"
#include "filter/xbrz.h"
//#undef FORCEINLINE
//#define FORCEINLINE
@ -444,8 +446,8 @@ public:
if (!CommonSettings.GFX3D_TXTHack)
{
iu = s32floor(u);
iv = s32floor(v);
iu = s32floor(u * (float)lastTexKey->GetRenderWidth() / (float)lastTexKey->GetWidth());
iv = s32floor(v * (float)lastTexKey->GetRenderHeight() / (float)lastTexKey->GetHeight());
}
else
{
@ -455,7 +457,7 @@ public:
sampler.dowrap(iu, iv);
FragmentColor color;
const u32 *textureData = lastTexKey->GetUnpackData();
const u32 *textureData = lastTexKey->GetRenderData();
color.color = textureData[( iv << lastTexKey->GetRenderWidthShift() ) + iu];
@ -1150,13 +1152,26 @@ SoftRasterizerTexture::SoftRasterizerTexture(u32 texAttributes, u32 palAttribute
{
_cacheSize = GetUnpackSizeUsingFormat(TexFormat_15bpp);
_unpackData = (u32 *)malloc_alignedCacheLine(_cacheSize);
_useDeposterize = false;
_scalingFactor = 1;
_customBuffer = NULL;
_renderData = _unpackData;
_renderWidth = _sizeS;
_renderHeight = _sizeT;
_renderWidthMask = _renderWidth - 1;
_renderHeightMask = _renderHeight - 1;
_renderWidthShift = 0;
memset(&_deposterizeSrcSurface, 0, sizeof(_deposterizeSrcSurface));
memset(&_deposterizeDstSurface, 0, sizeof(_deposterizeDstSurface));
_deposterizeSrcSurface.Width = _deposterizeDstSurface.Width = _sizeS;
_deposterizeSrcSurface.Height = _deposterizeDstSurface.Height = _sizeT;
_deposterizeSrcSurface.Pitch = _deposterizeDstSurface.Pitch = 1;
_deposterizeSrcSurface.Surface = (unsigned char *)_unpackData;
u32 tempWidth = _renderWidth;
while ( (tempWidth & 1) == 0)
{
@ -1168,11 +1183,61 @@ SoftRasterizerTexture::SoftRasterizerTexture(u32 texAttributes, u32 palAttribute
SoftRasterizerTexture::~SoftRasterizerTexture()
{
free_aligned(this->_unpackData);
free_aligned(this->_deposterizeDstSurface.Surface);
free_aligned(this->_customBuffer);
}
void SoftRasterizerTexture::Load(void *targetBuffer)
template <size_t SCALEFACTOR>
void SoftRasterizerTexture::_Upscale()
{
this->Unpack<TexFormat_15bpp>((u32 *)targetBuffer);
if ( (SCALEFACTOR != 2) && (SCALEFACTOR != 4) )
{
return;
}
u32 *src = (this->_useDeposterize) ? (u32 *)this->_deposterizeDstSurface.Surface : this->_unpackData;
if (this->_packFormat == TEXMODE_A3I5 || this->_packFormat == TEXMODE_A5I3)
{
xbrz::scale<SCALEFACTOR, xbrz::ColorFormatARGB>(src, this->_customBuffer, this->_sizeS, this->_sizeT);
}
else
{
xbrz::scale<SCALEFACTOR, xbrz::ColorFormatARGB_1bitAlpha>(src, this->_customBuffer, this->_sizeS, this->_sizeT);
}
}
void SoftRasterizerTexture::Load()
{
if (this->_scalingFactor == 1 && !this->_useDeposterize)
{
this->Unpack<TexFormat_15bpp>((u32 *)this->_renderData);
}
else
{
this->Unpack<TexFormat_32bpp>((u32 *)this->_unpackData);
if (this->_useDeposterize)
{
RenderDeposterize(this->_deposterizeSrcSurface, this->_deposterizeDstSurface);
}
switch (this->_scalingFactor)
{
case 2:
this->_Upscale<2>();
break;
case 4:
this->_Upscale<4>();
break;
default:
break;
}
ColorspaceConvertBuffer8888To6665<false, false>(this->_renderData, this->_renderData, this->_renderWidth * this->_renderHeight);
}
}
u32* SoftRasterizerTexture::GetUnpackData()
@ -1180,6 +1245,11 @@ u32* SoftRasterizerTexture::GetUnpackData()
return this->_unpackData;
}
u32* SoftRasterizerTexture::GetRenderData()
{
return this->_renderData;
}
u32 SoftRasterizerTexture::GetRenderWidth() const
{
return this->_renderWidth;
@ -1205,6 +1275,96 @@ u32 SoftRasterizerTexture::GetRenderWidthShift() const
return this->_renderWidthShift;
}
bool SoftRasterizerTexture::IsUsingDeposterize() const
{
return this->_useDeposterize;
}
void SoftRasterizerTexture::SetUseDeposterize(bool willDeposterize)
{
this->_useDeposterize = willDeposterize;
if ( (this->_deposterizeDstSurface.Surface == NULL) && willDeposterize )
{
this->_deposterizeDstSurface.Surface = (unsigned char *)malloc_alignedCacheLine(this->_cacheSize * 2);
this->_deposterizeDstSurface.workingSurface[0] = this->_deposterizeDstSurface.Surface + this->_cacheSize;
}
else if ( (this->_deposterizeDstSurface.Surface != NULL) && !willDeposterize )
{
free_aligned(this->_deposterizeDstSurface.Surface);
this->_deposterizeDstSurface.Surface = NULL;
}
if (this->_scalingFactor == 1)
{
if (this->_useDeposterize)
{
this->_renderData = (u32 *)this->_deposterizeDstSurface.Surface;
}
else
{
this->_renderData = this->_unpackData;
}
}
else
{
this->_renderData = this->_customBuffer;
}
}
size_t SoftRasterizerTexture::GetScalingFactor() const
{
return this->_scalingFactor;
}
void SoftRasterizerTexture::SetScalingFactor(size_t scalingFactor)
{
if ( (scalingFactor != 2) && (scalingFactor != 4) )
{
scalingFactor = 1;
}
u32 newWidth = this->_sizeS * scalingFactor;
u32 newHeight = this->_sizeT * scalingFactor;
if (this->_renderWidth != newWidth || this->_renderHeight != newHeight)
{
u32 *oldBuffer = this->_customBuffer;
this->_customBuffer = (u32 *)malloc_alignedCacheLine(newWidth * newHeight * sizeof(u32));
free_aligned(oldBuffer);
}
this->_scalingFactor = scalingFactor;
this->_renderWidth = newWidth;
this->_renderHeight = newHeight;
this->_renderWidthMask = newWidth - 1;
this->_renderHeightMask = newHeight - 1;
this->_renderWidthShift = 0;
u32 tempWidth = newWidth;
while ( (tempWidth & 1) == 0)
{
tempWidth >>= 1;
this->_renderWidthShift++;
}
if (this->_scalingFactor == 1)
{
if (this->_useDeposterize)
{
this->_renderData = (u32 *)this->_deposterizeDstSurface.Surface;
}
else
{
this->_renderData = this->_unpackData;
}
}
else
{
this->_renderData = this->_customBuffer;
}
}
GPU3DInterface gpu3DRasterize = {
"SoftRasterizer",
SoftRasterizerRendererCreate,
@ -1441,7 +1601,9 @@ void SoftRasterizerRenderer::setupTextures()
if (lastTexItem->IsLoadNeeded())
{
lastTexItem->Load(lastTexItem->GetUnpackData());
lastTexItem->SetUseDeposterize(this->_textureDeposterize);
lastTexItem->SetScalingFactor(this->_textureScalingFactor);
lastTexItem->Load();
}
for (size_t i = 0; i < this->_clippedPolyCount; i++)
@ -1464,7 +1626,9 @@ void SoftRasterizerRenderer::setupTextures()
if (lastTexItem->IsLoadNeeded())
{
lastTexItem->Load(lastTexItem->GetUnpackData());
lastTexItem->SetUseDeposterize(this->_textureDeposterize);
lastTexItem->SetScalingFactor(this->_textureScalingFactor);
lastTexItem->Load();
}
lastTexParams = thePoly.texParam;

View File

@ -44,24 +44,43 @@ class SoftRasterizerTexture : public TextureStore
{
protected:
u32 *_unpackData;
u32 *_renderData;
u32 _renderWidth;
u32 _renderHeight;
u32 _renderWidthMask;
u32 _renderHeightMask;
u32 _renderWidthShift;
bool _useDeposterize;
size_t _scalingFactor;
u32 *_customBuffer;
SSurface _deposterizeSrcSurface;
SSurface _deposterizeDstSurface;
template<size_t SCALEFACTOR> void _Upscale();
public:
SoftRasterizerTexture(u32 texAttributes, u32 palAttributes);
virtual ~SoftRasterizerTexture();
virtual void Load(void *targetBuffer);
virtual void Load();
u32* GetUnpackData();
u32* GetRenderData();
u32 GetRenderWidth() const;
u32 GetRenderHeight() const;
u32 GetRenderWidthMask() const;
u32 GetRenderHeightMask() const;
u32 GetRenderWidthShift() const;
bool IsUsingDeposterize() const;
void SetUseDeposterize(bool willDeposterize);
size_t GetScalingFactor() const;
void SetScalingFactor(size_t scalingFactor);
};
#if defined(ENABLE_SSE2)

View File

@ -234,6 +234,7 @@ Render3D::Render3D()
_willFlushFramebufferRGBA5551 = true;
_textureScalingFactor = 1;
_textureDeposterize = false;
_textureSmooth = false;
_textureUpscaleBuffer = NULL;
@ -346,7 +347,7 @@ void Render3D::SetTextureProcessingProperties(size_t scalingFactor, bool willDep
const size_t newScalingFactor = (isScaleValid) ? scalingFactor : 1;
bool needTexCacheReset = false;
if ( willDeposterize && (this->_textureDeposterizeDstSurface.Surface == NULL) )
if ( willDeposterize && !this->_textureDeposterize)
{
// 1024x1024 texels is the largest possible texture size.
// We need two buffers, one for each deposterize stage.
@ -357,14 +358,16 @@ void Render3D::SetTextureProcessingProperties(size_t scalingFactor, bool willDep
memset(this->_textureDeposterizeDstSurface.Surface, 0, bufferSize);
this->_textureDeposterize = true;
needTexCacheReset = true;
}
else if ( !willDeposterize && (this->_textureDeposterizeDstSurface.Surface != NULL) )
else if (!willDeposterize && this->_textureDeposterize)
{
free_aligned(this->_textureDeposterizeDstSurface.Surface);
this->_textureDeposterizeDstSurface.Surface = NULL;
this->_textureDeposterizeDstSurface.workingSurface[0] = NULL;
this->_textureDeposterize = false;
needTexCacheReset = true;
}

View File

@ -130,6 +130,7 @@ protected:
bool _willFlushFramebufferRGBA5551;
size_t _textureScalingFactor;
bool _textureDeposterize;
bool _textureSmooth;
SSurface _textureDeposterizeSrcSurface;