mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
this is a ugly unstable commit but i'm going to be out for work some days so ...
implemented donko's xfb in D3D: the bad things: *is solower in some cases, slower as opengl *it do not work in dual core mode, it seems direct3d has serious synchronization problems, to the other devs please if you can take a look and help me :) *real xfb still not working i have to give it more time to make it work. the good: *games that uses multiples xfbs will work now using the virtual XFB. *implemented a more hardware like approach to scaling, now to calculate the pixel scaling i use the xfb size not the efb so the screen pixels relation is more correct now. *simplified a little donko's virtual xfb to make it less memory consuming as xfb textures are the exact size of the scaled xfb and not full target width. * when it works even real xfb will let us use super sampling. I repeat this commit is totally unstable and in dual core mode it will for sure hang the emulator or at best give totally incorrect results. Other devs please help as thread sync is not one of my strong points :) i'll keep waiting for the comments an the -1 :) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5195 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -21,50 +21,148 @@
|
||||
#include <list>
|
||||
#include "D3DBase.h"
|
||||
|
||||
namespace FBManager
|
||||
// On the GameCube, the game sends a request for the graphics processor to
|
||||
// transfer its internal EFB (Embedded Framebuffer) to an area in GameCube RAM
|
||||
// called the XFB (External Framebuffer). The size and location of the XFB is
|
||||
// decided at the time of the copy, and the format is always YUYV. The video
|
||||
// interface is given a pointer to the XFB, which will be decoded and
|
||||
// displayed on the TV.
|
||||
//
|
||||
// There are two ways for Dolphin to emulate this:
|
||||
//
|
||||
// Real XFB mode:
|
||||
//
|
||||
// Dolphin will behave like the GameCube and encode the EFB to
|
||||
// a portion of GameCube RAM. The emulated video interface will decode the data
|
||||
// for output to the screen.
|
||||
//
|
||||
// Advantages: Behaves exactly like the GameCube.
|
||||
// Disadvantages: Resolution will be limited.
|
||||
//
|
||||
// Virtual XFB mode:
|
||||
//
|
||||
// When a request is made to copy the EFB to an XFB, Dolphin
|
||||
// will remember the RAM location and size of the XFB in a Virtual XFB list.
|
||||
// The video interface will look up the XFB in the list and use the enhanced
|
||||
// data stored there, if available.
|
||||
//
|
||||
// Advantages: Enables high resolution graphics, better than real hardware.
|
||||
// Disadvantages: If the GameCube CPU writes directly to the XFB (which is
|
||||
// possible but uncommon), the Virtual XFB will not capture this information.
|
||||
|
||||
// There may be multiple XFBs in GameCube RAM. This is the maximum number to
|
||||
// virtualize.
|
||||
const int MAX_VIRTUAL_XFB = 8;
|
||||
|
||||
inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
||||
{
|
||||
return !((aLower >= bUpper) || (bLower >= aUpper));
|
||||
}
|
||||
|
||||
void Create();
|
||||
void Destroy();
|
||||
struct XFBSource
|
||||
{
|
||||
XFBSource() :
|
||||
texture(0)
|
||||
{}
|
||||
|
||||
// To get the EFB in texture form, these functions may have to transfer
|
||||
// the EFB to a resolved texture first.
|
||||
LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc);
|
||||
LPDIRECT3DTEXTURE9 GetEFBDepthTexture(const EFBRectangle& sourceRc);
|
||||
|
||||
LPDIRECT3DSURFACE9 GetEFBColorRTSurface();
|
||||
LPDIRECT3DSURFACE9 GetEFBDepthRTSurface();
|
||||
LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface();
|
||||
LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface();
|
||||
D3DFORMAT GetEFBDepthRTSurfaceFormat();
|
||||
D3DFORMAT GetEFBColorRTSurfaceFormat();
|
||||
D3DFORMAT GetEFBDepthReadSurfaceFormat();
|
||||
LPDIRECT3DSURFACE9 GetEFBColorReadSurface();
|
||||
LPDIRECT3DSURFACE9 GetEFBDepthReadSurface();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
// Resolved framebuffer is only used in MSAA mode.
|
||||
LPDIRECT3DTEXTURE9 GetResolvedFramebuffer() const { return m_resolvedFramebuffer; }
|
||||
|
||||
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) const;
|
||||
|
||||
void SetFramebuffer(LPDIRECT3DSURFACE9 surface);
|
||||
|
||||
// If in MSAA mode, this will perform a resolve of the specified rectangle, and return the resolve target as a texture ID.
|
||||
// Thus, this call may be expensive. Don't repeat it unnecessarily.
|
||||
// If not in MSAA mode, will just return the render target texture ID.
|
||||
// After calling this, before you render anything else, you MUST bind the framebuffer you want to draw to.
|
||||
LPDIRECT3DTEXTURE9 ResolveAndGetRenderTarget(const EFBRectangle &rect);
|
||||
|
||||
// Same as above but for the depth Target.
|
||||
// After calling this, before you render anything else, you MUST bind the framebuffer you want to draw to.
|
||||
LPDIRECT3DTEXTURE9 ResolveAndGetDepthTarget(const EFBRectangle &rect);
|
||||
*/
|
||||
u32 srcAddr;
|
||||
u32 srcWidth;
|
||||
u32 srcHeight;
|
||||
|
||||
LPDIRECT3DTEXTURE9 texture;
|
||||
int texWidth;
|
||||
int texHeight;
|
||||
};
|
||||
|
||||
class FramebufferManager
|
||||
{
|
||||
public:
|
||||
FramebufferManager()
|
||||
{
|
||||
s_efb_color_texture = NULL;
|
||||
LPDIRECT3DTEXTURE9 s_efb_colorRead_texture = NULL;
|
||||
LPDIRECT3DTEXTURE9 s_efb_depth_texture = NULL;
|
||||
LPDIRECT3DTEXTURE9 s_efb_depthRead_texture = NULL;
|
||||
|
||||
LPDIRECT3DSURFACE9 s_efb_depth_surface = NULL;
|
||||
LPDIRECT3DSURFACE9 s_efb_color_surface = NULL;
|
||||
LPDIRECT3DSURFACE9 s_efb_color_ReadBuffer = NULL;
|
||||
LPDIRECT3DSURFACE9 s_efb_depth_ReadBuffer = NULL;
|
||||
LPDIRECT3DSURFACE9 s_efb_color_OffScreenReadBuffer = NULL;
|
||||
LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer = NULL;
|
||||
|
||||
D3DFORMAT s_efb_color_surface_Format = D3DFMT_FORCE_DWORD;
|
||||
D3DFORMAT s_efb_depth_surface_Format = D3DFMT_FORCE_DWORD;
|
||||
D3DFORMAT s_efb_depth_ReadBuffer_Format = D3DFMT_FORCE_DWORD;
|
||||
m_realXFBSource.texture = NULL;
|
||||
}
|
||||
|
||||
void Create();
|
||||
void Destroy();
|
||||
|
||||
void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||
|
||||
const XFBSource** GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||
|
||||
LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc);
|
||||
LPDIRECT3DTEXTURE9 GetEFBDepthTexture(const EFBRectangle& sourceRc);
|
||||
|
||||
LPDIRECT3DSURFACE9 GetEFBColorRTSurface();
|
||||
LPDIRECT3DSURFACE9 GetEFBDepthRTSurface();
|
||||
LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface();
|
||||
LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface();
|
||||
D3DFORMAT GetEFBDepthRTSurfaceFormat();
|
||||
D3DFORMAT GetEFBColorRTSurfaceFormat();
|
||||
D3DFORMAT GetEFBDepthReadSurfaceFormat();
|
||||
LPDIRECT3DSURFACE9 GetEFBColorReadSurface();
|
||||
LPDIRECT3DSURFACE9 GetEFBDepthReadSurface();
|
||||
|
||||
private:
|
||||
|
||||
struct VirtualXFB
|
||||
{
|
||||
// Address and size in GameCube RAM
|
||||
u32 xfbAddr;
|
||||
u32 xfbWidth;
|
||||
u32 xfbHeight;
|
||||
|
||||
XFBSource xfbSource;
|
||||
};
|
||||
|
||||
typedef std::list<VirtualXFB> VirtualXFBListType;
|
||||
|
||||
VirtualXFBListType::iterator findVirtualXFB(u32 xfbAddr, u32 width, u32 height);
|
||||
|
||||
void replaceVirtualXFB();
|
||||
|
||||
void copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||
void copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
|
||||
const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||
const XFBSource** getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
|
||||
|
||||
XFBSource m_realXFBSource; // Only used in Real XFB mode
|
||||
VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode
|
||||
|
||||
const XFBSource* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
|
||||
|
||||
LPDIRECT3DTEXTURE9 s_efb_color_texture;//Texture thats contains the color data of the render target
|
||||
LPDIRECT3DTEXTURE9 s_efb_colorRead_texture;//1 pixel texture for temporal data store
|
||||
LPDIRECT3DTEXTURE9 s_efb_depth_texture;//Texture thats contains the depth data of the render target
|
||||
LPDIRECT3DTEXTURE9 s_efb_depthRead_texture;//4 pixel texture for temporal data store
|
||||
|
||||
LPDIRECT3DSURFACE9 s_efb_depth_surface;//Depth Surface
|
||||
LPDIRECT3DSURFACE9 s_efb_color_surface;//Color Surface
|
||||
LPDIRECT3DSURFACE9 s_efb_color_ReadBuffer;//Surface 0 of s_efb_colorRead_texture
|
||||
LPDIRECT3DSURFACE9 s_efb_depth_ReadBuffer;//Surface 0 of s_efb_depthRead_texture
|
||||
LPDIRECT3DSURFACE9 s_efb_color_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data
|
||||
LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data
|
||||
|
||||
|
||||
D3DFORMAT s_efb_color_surface_Format;//Format of the color Surface
|
||||
D3DFORMAT s_efb_depth_surface_Format;//Format of the Depth Surface
|
||||
D3DFORMAT s_efb_depth_ReadBuffer_Format;//Format of the Depth color Read Surface
|
||||
};
|
||||
|
||||
extern FramebufferManager FBManager;
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user