fixed xfb bumping introduced by my last commit.

implemented loading of native mips, see sms water :).

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5366 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Rodolfo Osvaldo Bogado
2010-04-14 13:57:16 +00:00
parent 1483715567
commit a25dfc47b4
10 changed files with 123 additions and 33 deletions

View File

@ -21,7 +21,7 @@
namespace D3D
{
LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b)
LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b, int levels)
{
u32* pBuffer = (u32*)buffer;
LPDIRECT3DTEXTURE9 pTexture;
@ -38,8 +38,8 @@ LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int
HRESULT hr;
// TODO(ector): Allow mipmaps for non-pow textures on newer cards?
// TODO(ector): Use the game-specified mipmaps?
if (!isPow2)
hr = dev->CreateTexture(width, height, 1, 0, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
if (levels > 0)
hr = dev->CreateTexture(width, height, levels, 0, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
else
hr = dev->CreateTexture(width, height, 0, D3DUSAGE_AUTOGENMIPMAP, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
@ -148,10 +148,9 @@ LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFOR
return pTexture;
}
void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b)
void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b, int level)
{
u32* pBuffer = (u32*)buffer;
int level = 0;
D3DLOCKED_RECT Lock;
pTexture->LockRect(level, &Lock, NULL, 0);
u32* pIn = pBuffer;

View File

@ -21,8 +21,8 @@
namespace D3D
{
LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt = D3DFMT_A8R8G8B8, bool swap_r_b = false);
void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b);
LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt = D3DFMT_A8R8G8B8, bool swap_r_b = false, int levels = 1);
void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height, const int pitch, D3DFORMAT fmt, bool swap_r_b, int level = 0);
LPDIRECT3DTEXTURE9 CreateRenderTarget(const int width, const int height);
LPDIRECT3DSURFACE9 CreateDepthStencilSurface(const int width, const int height);
LPDIRECT3DTEXTURE9 CreateOnlyTexture2D(const int width, const int height, D3DFORMAT fmt);

View File

@ -1015,6 +1015,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
// EFB is copied to XFB. In this way, flickering is reduced in games
// and seems to also give more FPS in ZTP
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
u32 xfbCount = 0;
const XFBSource** xfbSourceList = FBManager.GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
if (!xfbSourceList || xfbCount == 0)
@ -1389,6 +1390,7 @@ void Renderer::SetSamplerState(int stage, int texindex)
{
const FourTexUnits &tex = bpmem.tex[texindex];
const TexMode0 &tm0 = tex.texMode0[stage];
const TexMode1 &tm1 = tex.texMode1[stage];
D3DTEXTUREFILTERTYPE min, mag, mip;
if (g_ActiveConfig.bForceFiltering)
@ -1399,7 +1401,7 @@ void Renderer::SetSamplerState(int stage, int texindex)
{
min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT;
mag = tm0.mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT;
mip = d3dMipFilters[tm0.min_filter & 3];
mip = (tm0.min_filter == 8)?D3DTEXF_NONE:d3dMipFilters[tm0.min_filter & 3];
}
if (texindex)
stage += 4;
@ -1415,11 +1417,9 @@ void Renderer::SetSamplerState(int stage, int texindex)
D3D::SetSamplerState(stage, D3DSAMP_ADDRESSU, d3dClamps[tm0.wrap_s]);
D3D::SetSamplerState(stage, D3DSAMP_ADDRESSV, d3dClamps[tm0.wrap_t]);
//wip
//dev->SetSamplerState(stage,D3DSAMP_MIPMAPLODBIAS,tm0.lod_bias/4.0f);
//char temp[256];
//sprintf(temp,"lod %f",tm0.lod_bias/4.0f);
//g_VideoInitialize.pLog(temp);
//just a test but it seems to work
D3D::SetSamplerState(stage,D3DSAMP_MIPMAPLODBIAS,tm0.lod_bias/2.0f);
D3D::SetSamplerState(stage,D3DSAMP_MAXMIPLEVEL,tm1.min_lod>>4);
}
void Renderer::SetInterlacingMode()

View File

@ -136,7 +136,7 @@ void TextureCache::Cleanup()
}
}
TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, int height, int tex_format, int tlutaddr, int tlutfmt)
TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, int height, int tex_format, int tlutaddr, int tlutfmt,bool UseNativeMips, int maxlevel)
{
if (address == 0)
return NULL;
@ -144,6 +144,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; //TexelSizeInNibbles(format)*width*height/16;
int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; //TexelSizeInNibbles(format)*width*height/16;
int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format);
int expandedWidth = (width + bsw) & (~bsw);
int expandedHeight = (height + bsh) & (~bsh);
@ -279,12 +280,41 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
entry.addr = address;
entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, tex_format);
entry.isRenderTarget = false;
entry.isNonPow2 = false;//((width & (width - 1)) || (height & (height - 1)));
if (!skip_texture_create) {
entry.texture = D3D::CreateTexture2D((BYTE*)temp, width, height, expandedWidth, d3d_fmt, swap_r_b);
} else {
bool isPow2 = !((width & (width - 1)) || (height & (height - 1)));
entry.isNonPow2 = false;
int TexLevels = (width > height)?width:height;
TexLevels = (isPow2 && UseNativeMips) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : (isPow2?0:1);
if(TexLevels > maxlevel && maxlevel > 0)
TexLevels = maxlevel;
if (!skip_texture_create)
{
entry.texture = D3D::CreateTexture2D((BYTE*)temp, width, height, expandedWidth, d3d_fmt, swap_r_b,TexLevels);
}
else
{
D3D::ReplaceTexture2D(entry.texture, (BYTE*)temp, width, height, expandedWidth, d3d_fmt, swap_r_b);
}
if(TexLevels > 1 && pcfmt != PC_TEX_FMT_NONE)
{
int level = 1;
int mipWidth = (width + 1) >> 1;
int mipHeight = (height + 1) >> 1;
ptr += entry.size_in_bytes;
while((mipHeight || mipWidth) && (level < TexLevels))
{
u32 currentWidth = (mipWidth > 0)? mipWidth : 1;
u32 currentHeight = (mipHeight > 0)? mipHeight : 1;
expandedWidth = (currentWidth + bsw) & (~bsw);
expandedHeight = (currentHeight + bsh) & (~bsh);
TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt);
D3D::ReplaceTexture2D(entry.texture, (BYTE*)temp, currentWidth, currentHeight, expandedWidth, d3d_fmt, swap_r_b,level);
u32 size = (max(mipWidth, bsw) * max(mipHeight, bsh) * bsdepth) >> 1;
ptr += size;
mipWidth >>= 1;
mipHeight >>= 1;
level++;
}
}
entry.frameCount = frameCount;
entry.w = width;
entry.h = height;

View File

@ -82,7 +82,7 @@ public:
static void Shutdown();
static void Invalidate(bool shutdown);
static void InvalidateRange(u32 start_address, u32 size);
static TCacheEntry *Load(int stage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt);
static TCacheEntry *Load(int stage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt,bool UseNativeMips, int maxlevel);
static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source_rect);
};

View File

@ -249,7 +249,9 @@ void Flush()
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1,
tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9,
tex.texTlut[i&3].tlut_format);
tex.texTlut[i&3].tlut_format,
(tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8),
(tex.texMode1[i&3].max_lod >> 4));
if (tentry) {
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);