2009-09-13 17:46:33 +00:00
|
|
|
// Copyright (C) 2003 Dolphin Project.
|
|
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, version 2.0.
|
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
// Official SVN repository and contact information can be found at
|
|
|
|
// http://code.google.com/p/dolphin-emu/
|
|
|
|
|
|
|
|
#include "D3DBase.h"
|
|
|
|
#include "Render.h"
|
|
|
|
#include "FramebufferManager.h"
|
2009-10-08 00:35:47 +00:00
|
|
|
#include "VideoConfig.h"
|
2009-09-13 17:46:33 +00:00
|
|
|
|
|
|
|
namespace FBManager
|
|
|
|
{
|
|
|
|
|
2009-11-08 20:35:11 +00:00
|
|
|
static LPDIRECT3DTEXTURE9 s_efb_color_texture;//Texture thats contains the color data of the render target
|
|
|
|
static LPDIRECT3DTEXTURE9 s_efb_colorRead_texture;//1 pixel texture for temporal data store
|
|
|
|
static LPDIRECT3DTEXTURE9 s_efb_depth_texture;//Texture thats contains the depth data of the render target
|
2009-11-22 02:37:00 +00:00
|
|
|
static LPDIRECT3DTEXTURE9 s_efb_depthRead_texture;//4 pixel texture for temporal data store
|
2009-10-08 00:35:47 +00:00
|
|
|
|
2009-11-08 20:35:11 +00:00
|
|
|
static LPDIRECT3DSURFACE9 s_efb_depth_surface;//Depth Surface
|
|
|
|
static LPDIRECT3DSURFACE9 s_efb_color_surface;//Color Surface
|
|
|
|
static LPDIRECT3DSURFACE9 s_efb_color_ReadBuffer;//Surface 0 of s_efb_colorRead_texture
|
|
|
|
static LPDIRECT3DSURFACE9 s_efb_depth_ReadBuffer;//Surface 0 of s_efb_depthRead_texture
|
2009-10-10 23:36:18 +00:00
|
|
|
|
2009-11-08 20:35:11 +00:00
|
|
|
static LPDIRECT3DSURFACE9 s_efb_color_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data
|
|
|
|
static LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data
|
2009-10-08 00:35:47 +00:00
|
|
|
|
|
|
|
|
2009-11-08 20:35:11 +00:00
|
|
|
static D3DFORMAT s_efb_color_surface_Format;//Format of the color Surface
|
2009-11-22 02:37:00 +00:00
|
|
|
static D3DFORMAT s_efb_depth_surface_Format;//Format of the Depth Surface
|
|
|
|
static D3DFORMAT s_efb_depth_ReadBuffer_Format;//Format of the Depth color Read Surface
|
2009-09-13 17:46:33 +00:00
|
|
|
#undef CHECK
|
2009-10-25 02:35:21 +00:00
|
|
|
#define CHECK(hr,Message) if (FAILED(hr)) { PanicAlert(__FUNCTION__ " FAIL: %s" ,Message); }
|
2009-10-10 23:36:18 +00:00
|
|
|
|
|
|
|
|
2009-09-13 17:46:33 +00:00
|
|
|
|
2009-11-08 20:35:11 +00:00
|
|
|
LPDIRECT3DSURFACE9 GetEFBColorRTSurface()
|
|
|
|
{
|
|
|
|
return s_efb_color_surface;
|
|
|
|
}
|
|
|
|
LPDIRECT3DSURFACE9 GetEFBDepthRTSurface()
|
|
|
|
{
|
|
|
|
return s_efb_depth_surface;
|
|
|
|
}
|
|
|
|
|
|
|
|
LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface()
|
|
|
|
{
|
|
|
|
return s_efb_color_OffScreenReadBuffer;
|
|
|
|
}
|
|
|
|
LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface()
|
|
|
|
{
|
|
|
|
return s_efb_depth_OffScreenReadBuffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
LPDIRECT3DSURFACE9 GetEFBColorReadSurface()
|
2009-11-22 02:37:00 +00:00
|
|
|
{
|
2009-11-08 20:35:11 +00:00
|
|
|
return s_efb_color_ReadBuffer;
|
|
|
|
}
|
2009-11-22 02:37:00 +00:00
|
|
|
|
2009-11-08 20:35:11 +00:00
|
|
|
LPDIRECT3DSURFACE9 GetEFBDepthReadSurface()
|
2009-11-22 02:37:00 +00:00
|
|
|
{
|
2009-11-08 20:35:11 +00:00
|
|
|
return s_efb_depth_ReadBuffer;
|
|
|
|
}
|
2009-10-10 23:36:18 +00:00
|
|
|
|
2009-10-06 14:24:10 +00:00
|
|
|
D3DFORMAT GetEFBDepthRTSurfaceFormat(){return s_efb_depth_surface_Format;}
|
2009-11-22 02:37:00 +00:00
|
|
|
D3DFORMAT GetEFBDepthReadSurfaceFormat(){return s_efb_depth_ReadBuffer_Format;}
|
2009-10-06 14:24:10 +00:00
|
|
|
D3DFORMAT GetEFBColorRTSurfaceFormat(){return s_efb_color_surface_Format;}
|
2009-09-13 17:46:33 +00:00
|
|
|
|
2009-11-22 02:37:00 +00:00
|
|
|
|
2009-09-15 20:18:25 +00:00
|
|
|
LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc)
|
|
|
|
{
|
|
|
|
return s_efb_color_texture;
|
|
|
|
}
|
|
|
|
|
2009-10-10 23:36:18 +00:00
|
|
|
|
2009-09-15 21:05:31 +00:00
|
|
|
LPDIRECT3DTEXTURE9 GetEFBDepthTexture(const EFBRectangle &sourceRc)
|
|
|
|
{
|
2009-10-10 23:36:18 +00:00
|
|
|
return s_efb_depth_texture;
|
2009-09-15 21:05:31 +00:00
|
|
|
}
|
|
|
|
|
2009-11-22 02:37:00 +00:00
|
|
|
|
|
|
|
|
2009-09-13 17:46:33 +00:00
|
|
|
void Create()
|
2009-11-22 02:37:00 +00:00
|
|
|
{
|
2009-09-13 17:46:33 +00:00
|
|
|
// Simplest possible setup to start with.
|
ok big changes here:
in videocommon little fix for the alpha test values, return to the original values as they are more accurate.
in D3D:
huge change in state management, now all the state management is centralized and redundant state changes are eliminated.
Fixed the overlapped viewport error in non ati cards:
the error was caused by this: when a viewport is defined larger than the current rendertarget, an error is thrown and the last valid viewport is used, this is the reference behavior, in ati cards if a larger viewport is defined, no eror is returned, the rendering is valid and is rendered using the projection defined by the viewport but limited to the rendertarget are, exactly like opengl or the GC hardware.
to solve this in reference drivers defined a large rendertarget (2x the size of the original) and proceed to render in a centered quad insithe the larger rendertarget, in this way larger viewports always falls inside a valid rendertarget size, the drawback of this is the waste of resources. it can be dynamized, depending or games or changed at runtime when a oversized viewport is detected, but i live that to future commits.
please test this and let me know the results.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4841 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-01-15 15:52:08 +00:00
|
|
|
int target_width = Renderer::GetFullTargetWidth();
|
|
|
|
int target_height = Renderer::GetFullTargetHeight();
|
2009-12-22 06:47:42 +00:00
|
|
|
|
2009-10-06 14:24:10 +00:00
|
|
|
s_efb_color_surface_Format = D3DFMT_A8R8G8B8;
|
2009-10-10 23:36:18 +00:00
|
|
|
//get the framebuffer texture
|
2009-11-08 20:35:11 +00:00
|
|
|
HRESULT hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
|
2009-09-15 20:18:25 +00:00
|
|
|
D3DPOOL_DEFAULT, &s_efb_color_texture, NULL);
|
2009-11-08 20:35:11 +00:00
|
|
|
if(s_efb_color_texture)
|
|
|
|
{
|
2009-11-22 02:37:00 +00:00
|
|
|
hr = s_efb_color_texture->GetSurfaceLevel(0,&s_efb_color_surface);
|
2009-11-08 20:35:11 +00:00
|
|
|
}
|
2009-10-10 23:36:18 +00:00
|
|
|
CHECK(hr,"Create Color Texture");
|
2009-11-08 20:35:11 +00:00
|
|
|
hr = D3D::dev->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
|
|
|
|
D3DPOOL_DEFAULT, &s_efb_colorRead_texture, NULL);
|
|
|
|
CHECK(hr,"Create Color Read Texture");
|
|
|
|
if(s_efb_colorRead_texture)
|
2009-10-10 23:36:18 +00:00
|
|
|
{
|
2009-11-08 20:35:11 +00:00
|
|
|
s_efb_colorRead_texture->GetSurfaceLevel(0,&s_efb_color_ReadBuffer);
|
2009-10-10 23:36:18 +00:00
|
|
|
}
|
2009-11-08 20:35:11 +00:00
|
|
|
//create an offscreen surface that we can lock to retrieve the data
|
|
|
|
hr = D3D::dev->CreateOffscreenPlainSurface(1, 1, s_efb_color_surface_Format, D3DPOOL_SYSTEMMEM, &s_efb_color_OffScreenReadBuffer, NULL );
|
|
|
|
CHECK(hr,"Create Color offScreen Surface");
|
2009-10-10 23:36:18 +00:00
|
|
|
|
2009-10-06 14:24:10 +00:00
|
|
|
//Select Zbuffer format supported by hadware.
|
2009-10-08 00:35:47 +00:00
|
|
|
if (g_ActiveConfig.bEFBAccessEnable)
|
2009-11-22 02:37:00 +00:00
|
|
|
{
|
|
|
|
D3DFORMAT *DepthTexFormats = new D3DFORMAT[5];
|
|
|
|
DepthTexFormats[0] = FOURCC_INTZ;
|
|
|
|
DepthTexFormats[1] = FOURCC_DF24;
|
|
|
|
DepthTexFormats[2] = FOURCC_RAWZ;
|
|
|
|
DepthTexFormats[3] = FOURCC_DF16;
|
|
|
|
DepthTexFormats[4] = D3DFMT_D24X8;
|
|
|
|
|
|
|
|
for(int i = 0;i<5;i++)
|
|
|
|
{
|
|
|
|
s_efb_depth_surface_Format = DepthTexFormats[i];
|
|
|
|
//get the framebuffer Depth texture
|
|
|
|
hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_DEPTHSTENCIL, s_efb_depth_surface_Format,
|
|
|
|
D3DPOOL_DEFAULT, &s_efb_depth_texture, NULL);
|
|
|
|
if (!FAILED(hr)) break;
|
|
|
|
}
|
|
|
|
CHECK(hr,"Depth Color Texture");
|
|
|
|
//get the Surface
|
|
|
|
if(s_efb_depth_texture)
|
|
|
|
{
|
|
|
|
s_efb_depth_texture->GetSurfaceLevel(0,&s_efb_depth_surface);
|
|
|
|
}
|
|
|
|
//create a 4x4 pixel texture to work as a buffer for peeking
|
|
|
|
if(s_efb_depth_surface_Format == FOURCC_RAWZ || s_efb_depth_surface_Format == D3DFMT_D24X8)
|
2009-11-08 20:35:11 +00:00
|
|
|
{
|
2009-11-22 02:37:00 +00:00
|
|
|
DepthTexFormats[0] = D3DFMT_A8R8G8B8;
|
2009-11-08 20:35:11 +00:00
|
|
|
}
|
2009-11-10 12:45:03 +00:00
|
|
|
else
|
2009-11-08 20:35:11 +00:00
|
|
|
{
|
2009-11-22 02:37:00 +00:00
|
|
|
DepthTexFormats[0] = D3DFMT_R32F;
|
2009-11-08 20:35:11 +00:00
|
|
|
}
|
2009-11-22 02:37:00 +00:00
|
|
|
DepthTexFormats[1] = D3DFMT_A8R8G8B8;
|
|
|
|
|
|
|
|
for(int i = 0;i<2;i++)
|
|
|
|
{
|
|
|
|
s_efb_depth_ReadBuffer_Format = DepthTexFormats[i];
|
|
|
|
//get the framebuffer Depth texture
|
|
|
|
hr = D3D::dev->CreateTexture(4, 4, 1, D3DUSAGE_RENDERTARGET, s_efb_depth_ReadBuffer_Format,
|
|
|
|
D3DPOOL_DEFAULT, &s_efb_depthRead_texture, NULL);
|
|
|
|
if (!FAILED(hr)) break;
|
|
|
|
}
|
|
|
|
|
|
|
|
CHECK(hr,"Create Depth Read texture");
|
|
|
|
if(s_efb_depthRead_texture)
|
|
|
|
{
|
|
|
|
s_efb_depthRead_texture->GetSurfaceLevel(0,&s_efb_depth_ReadBuffer);
|
|
|
|
}
|
|
|
|
//create an offscreen surface that we can lock to retrieve the data
|
|
|
|
hr = D3D::dev->CreateOffscreenPlainSurface(4, 4, s_efb_depth_ReadBuffer_Format, D3DPOOL_SYSTEMMEM, &s_efb_depth_OffScreenReadBuffer, NULL );
|
|
|
|
CHECK(hr,"Create Depth offScreen Surface");
|
|
|
|
delete [] DepthTexFormats;
|
2009-10-08 00:35:47 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-10-10 23:36:18 +00:00
|
|
|
s_efb_depth_surface_Format = D3DFMT_D24X8;
|
|
|
|
hr = D3D::dev->CreateDepthStencilSurface(target_width, target_height, s_efb_depth_surface_Format,
|
2009-10-08 00:35:47 +00:00
|
|
|
D3DMULTISAMPLE_NONE, 0, FALSE, &s_efb_depth_surface, NULL);
|
2009-11-22 02:37:00 +00:00
|
|
|
CHECK(hr,"CreateDepthStencilSurface");
|
2009-10-08 00:35:47 +00:00
|
|
|
}
|
2009-09-13 17:46:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Destroy()
|
|
|
|
{
|
2009-10-10 23:36:18 +00:00
|
|
|
|
2009-11-08 20:35:11 +00:00
|
|
|
if(s_efb_depth_surface)
|
|
|
|
s_efb_depth_surface->Release();
|
|
|
|
s_efb_depth_surface=NULL;
|
2009-10-08 00:35:47 +00:00
|
|
|
|
2009-11-08 20:35:11 +00:00
|
|
|
if(s_efb_color_surface)
|
|
|
|
s_efb_color_surface->Release();
|
|
|
|
s_efb_color_surface=NULL;
|
2009-10-10 23:36:18 +00:00
|
|
|
|
2009-11-08 20:35:11 +00:00
|
|
|
if(s_efb_color_ReadBuffer)
|
|
|
|
s_efb_color_ReadBuffer->Release();
|
|
|
|
s_efb_color_ReadBuffer=NULL;
|
|
|
|
|
|
|
|
if(s_efb_depth_ReadBuffer)
|
|
|
|
s_efb_depth_ReadBuffer->Release();
|
|
|
|
s_efb_depth_ReadBuffer=NULL;
|
|
|
|
|
|
|
|
if(s_efb_color_OffScreenReadBuffer)
|
|
|
|
s_efb_color_OffScreenReadBuffer->Release();
|
|
|
|
s_efb_color_OffScreenReadBuffer=NULL;
|
|
|
|
|
|
|
|
if(s_efb_depth_OffScreenReadBuffer)
|
|
|
|
s_efb_depth_OffScreenReadBuffer->Release();
|
|
|
|
s_efb_depth_OffScreenReadBuffer=NULL;
|
|
|
|
|
|
|
|
if(s_efb_color_texture)
|
|
|
|
s_efb_color_texture->Release();
|
|
|
|
s_efb_color_texture=NULL;
|
|
|
|
|
|
|
|
if(s_efb_colorRead_texture)
|
|
|
|
s_efb_colorRead_texture->Release();
|
|
|
|
s_efb_colorRead_texture=NULL;
|
|
|
|
|
|
|
|
if(s_efb_depth_texture)
|
|
|
|
s_efb_depth_texture->Release();
|
|
|
|
s_efb_depth_texture=NULL;
|
|
|
|
|
|
|
|
if(s_efb_depthRead_texture)
|
|
|
|
s_efb_depthRead_texture->Release();
|
|
|
|
s_efb_depthRead_texture=NULL;
|
2009-10-10 23:36:18 +00:00
|
|
|
|
2009-09-13 17:46:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|