2013-04-18 03:29:41 +00:00
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
2008-12-08 05:25:12 +00:00
2009-02-28 22:10:38 +00:00
# include <list>
2008-12-08 05:25:12 +00:00
# include <d3dx9.h>
2010-01-29 07:44:21 +00:00
# include "StringUtil.h"
2008-12-08 05:25:12 +00:00
# include "Common.h"
2010-03-14 18:57:50 +00:00
# include "Atomic.h"
2010-02-02 21:56:29 +00:00
# include "FileUtil.h"
2010-01-27 22:07:59 +00:00
# include "Thread.h"
2010-01-21 21:27:52 +00:00
# include "Timer.h"
2008-12-08 05:25:12 +00:00
# include "Statistics.h"
2011-03-15 23:09:12 +00:00
# include "Host.h"
2008-12-08 05:25:12 +00:00
2009-09-13 09:23:30 +00:00
# include "VideoConfig.h"
2008-12-08 05:25:12 +00:00
# include "main.h"
# include "VertexManager.h"
2010-10-24 19:52:52 +00:00
# include "PixelEngine.h"
2008-12-08 05:25:12 +00:00
# include "Render.h"
# include "OpcodeDecoding.h"
2009-06-22 09:31:30 +00:00
# include "BPStructs.h"
2008-12-08 05:25:12 +00:00
# include "XFStructs.h"
# include "D3DUtil.h"
2008-12-25 15:56:36 +00:00
# include "VertexShaderManager.h"
# include "PixelShaderManager.h"
2009-02-28 22:10:38 +00:00
# include "VertexShaderCache.h"
2008-12-26 19:39:12 +00:00
# include "PixelShaderCache.h"
2009-09-13 17:46:33 +00:00
# include "VertexLoaderManager.h"
2008-12-08 05:25:12 +00:00
# include "TextureCache.h"
# include "EmuWindow.h"
2009-03-28 21:07:16 +00:00
# include "AVIDump.h"
2009-09-03 20:37:35 +00:00
# include "OnScreenDisplay.h"
2009-09-13 17:46:33 +00:00
# include "FramebufferManager.h"
2009-09-04 06:09:21 +00:00
# include "Fifo.h"
Well this commit has 2 parts:
first part if fixing, fixed, i thing, the flickering that everyone has reported, at least in my case i only have flickering in the one texture in one game and now is fixed. The other fix is not for an reported issue, is more a correctness fix, running dolphin with pix to review debug errors, result in a ton of warnings and error, now with this commit, at least for ati, there no more error or warnings, this means, correct management and state change, no accurate emulation, for this still a lot of work to do.
for this part of the commit please give me feedback and let me know of remaining issues
Te second part is the partial implementation of efb to ram copy in d3d, this won't brake anything because is commented but i commit this to ask for help from ector and donko in some errors remaining in the implementation related to differences between opengl an d3d.
if you want to test this you have to uncomment line 150 to 155 of bpstruct.cpp
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4594 8ced0084-cf51-0410-be5f-012b33b47a6e
2009-11-20 18:46:30 +00:00
# include "TextureConverter.h"
2010-08-29 23:08:56 +00:00
# include "DLCache.h"
2010-12-05 14:15:36 +00:00
# include "Debugger.h"
2011-01-31 01:28:32 +00:00
# include "Core.h"
2011-06-24 06:50:50 +00:00
# include "Movie.h"
2011-09-05 20:04:28 +00:00
# include "BPFunctions.h"
2012-10-04 03:41:02 +00:00
# include "FPSCounter.h"
2012-11-11 22:57:06 +00:00
# include "ConfigManager.h"
2013-04-03 22:53:48 +00:00
# include "PerfQuery.h"
2012-12-23 07:25:11 +00:00
# include <strsafe.h>
2011-01-29 20:16:51 +00:00
namespace DX9
{
2010-09-28 02:15:02 +00:00
static int s_fps = 0 ;
2010-02-20 04:18:19 +00:00
2009-10-10 23:36:18 +00:00
static u32 s_blendMode ;
2010-02-03 22:19:00 +00:00
static u32 s_LastAA ;
2010-02-04 22:25:09 +00:00
static bool IS_AMD ;
2012-11-12 22:37:08 +00:00
static float m_fMaxPointSize ;
2013-04-01 17:23:48 +00:00
static bool s_vsync ;
2010-06-20 22:23:34 +00:00
static char * st ;
2008-12-08 05:25:12 +00:00
2010-01-27 22:07:59 +00:00
static LPDIRECT3DSURFACE9 ScreenShootMEMSurface = NULL ;
2009-11-08 20:35:11 +00:00
2009-09-13 17:46:33 +00:00
void SetupDeviceObjects ( )
{
D3D : : font . Init ( ) ;
VertexLoaderManager : : Init ( ) ;
2010-11-14 23:31:53 +00:00
g_framebuffer_manager = new FramebufferManager ;
2009-09-15 21:05:31 +00:00
2009-09-15 21:49:15 +00:00
VertexShaderManager : : Dirty ( ) ;
PixelShaderManager : : Dirty ( ) ;
Well this commit has 2 parts:
first part if fixing, fixed, i thing, the flickering that everyone has reported, at least in my case i only have flickering in the one texture in one game and now is fixed. The other fix is not for an reported issue, is more a correctness fix, running dolphin with pix to review debug errors, result in a ton of warnings and error, now with this commit, at least for ati, there no more error or warnings, this means, correct management and state change, no accurate emulation, for this still a lot of work to do.
for this part of the commit please give me feedback and let me know of remaining issues
Te second part is the partial implementation of efb to ram copy in d3d, this won't brake anything because is commented but i commit this to ask for help from ector and donko in some errors remaining in the implementation related to differences between opengl an d3d.
if you want to test this you have to uncomment line 150 to 155 of bpstruct.cpp
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4594 8ced0084-cf51-0410-be5f-012b33b47a6e
2009-11-20 18:46:30 +00:00
TextureConverter : : Init ( ) ;
2010-06-19 16:22:24 +00:00
// To avoid shader compilation stutters, read back all shaders from cache.
VertexShaderCache : : Init ( ) ;
PixelShaderCache : : Init ( ) ;
2012-10-20 13:22:15 +00:00
g_vertex_manager - > CreateDeviceObjects ( ) ;
2013-04-04 15:53:06 +00:00
( ( PerfQuery * ) g_perf_query ) - > CreateDeviceObjects ( ) ;
2010-06-19 16:22:24 +00:00
// Texture cache will recreate themselves over time.
2009-09-13 17:46:33 +00:00
}
// Kill off all POOL_DEFAULT device objects.
void TeardownDeviceObjects ( )
{
2010-01-28 04:30:07 +00:00
if ( ScreenShootMEMSurface )
ScreenShootMEMSurface - > Release ( ) ;
ScreenShootMEMSurface = NULL ;
2009-09-15 19:53:22 +00:00
D3D : : dev - > SetRenderTarget ( 0 , D3D : : GetBackBufferSurface ( ) ) ;
D3D : : dev - > SetDepthStencilSurface ( D3D : : GetBackBufferDepthSurface ( ) ) ;
2010-11-14 23:31:53 +00:00
delete g_framebuffer_manager ;
2013-04-04 15:53:06 +00:00
( ( PerfQuery * ) g_perf_query ) - > DestroyDeviceObjects ( ) ;
2009-09-13 17:46:33 +00:00
D3D : : font . Shutdown ( ) ;
2012-05-28 09:37:14 +00:00
TextureCache : : Invalidate ( ) ;
2009-09-13 17:46:33 +00:00
VertexLoaderManager : : Shutdown ( ) ;
2010-06-19 16:22:24 +00:00
VertexShaderCache : : Shutdown ( ) ;
PixelShaderCache : : Shutdown ( ) ;
Well this commit has 2 parts:
first part if fixing, fixed, i thing, the flickering that everyone has reported, at least in my case i only have flickering in the one texture in one game and now is fixed. The other fix is not for an reported issue, is more a correctness fix, running dolphin with pix to review debug errors, result in a ton of warnings and error, now with this commit, at least for ati, there no more error or warnings, this means, correct management and state change, no accurate emulation, for this still a lot of work to do.
for this part of the commit please give me feedback and let me know of remaining issues
Te second part is the partial implementation of efb to ram copy in d3d, this won't brake anything because is commented but i commit this to ask for help from ector and donko in some errors remaining in the implementation related to differences between opengl an d3d.
if you want to test this you have to uncomment line 150 to 155 of bpstruct.cpp
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4594 8ced0084-cf51-0410-be5f-012b33b47a6e
2009-11-20 18:46:30 +00:00
TextureConverter : : Shutdown ( ) ;
2012-10-20 13:22:15 +00:00
g_vertex_manager - > DestroyDeviceObjects ( ) ;
2009-09-13 17:46:33 +00:00
}
2010-09-28 02:15:02 +00:00
// Init functions
2010-11-18 02:21:26 +00:00
Renderer : : Renderer ( )
2008-12-08 05:25:12 +00:00
{
2012-10-04 03:41:02 +00:00
InitFPSCounter ( ) ;
2010-06-20 22:23:34 +00:00
st = new char [ 32768 ] ;
2010-11-18 02:21:26 +00:00
2010-04-22 04:28:34 +00:00
int fullScreenRes , x , y , w_temp , h_temp ;
2010-01-28 13:38:09 +00:00
s_blendMode = 0 ;
2010-06-05 00:01:18 +00:00
// Multisample Anti-aliasing hasn't been implemented yet use supersamling instead
int backbuffer_ms_mode = 0 ;
2009-09-15 08:13:45 +00:00
2011-03-15 23:09:12 +00:00
Host_GetRenderWindowSize ( x , y , w_temp , h_temp ) ;
2009-09-15 08:13:45 +00:00
2009-11-08 02:28:06 +00:00
for ( fullScreenRes = 0 ; fullScreenRes < ( int ) D3D : : GetAdapter ( g_ActiveConfig . iAdapter ) . resolutions . size ( ) ; fullScreenRes + + )
2009-09-15 08:13:45 +00:00
{
2009-09-17 05:07:16 +00:00
if ( ( D3D : : GetAdapter ( g_ActiveConfig . iAdapter ) . resolutions [ fullScreenRes ] . xres = = w_temp ) & &
( D3D : : GetAdapter ( g_ActiveConfig . iAdapter ) . resolutions [ fullScreenRes ] . yres = = h_temp ) )
2009-09-15 08:13:45 +00:00
break ;
}
2009-09-17 05:57:38 +00:00
if ( fullScreenRes = = D3D : : GetAdapter ( g_ActiveConfig . iAdapter ) . resolutions . size ( ) )
fullScreenRes = 0 ;
2010-07-06 13:14:51 +00:00
D3D : : Create ( g_ActiveConfig . iAdapter , EmuWindow : : GetWnd ( ) ,
2009-09-15 19:53:22 +00:00
fullScreenRes , backbuffer_ms_mode , false ) ;
2008-12-08 05:25:12 +00:00
2010-02-04 22:25:09 +00:00
IS_AMD = D3D : : IsATIDevice ( ) ;
2010-09-28 02:15:02 +00:00
2013-04-19 13:21:45 +00:00
// Decide framebuffer size
2009-09-13 17:46:33 +00:00
s_backbuffer_width = D3D : : GetBackBufferWidth ( ) ;
s_backbuffer_height = D3D : : GetBackBufferHeight ( ) ;
2009-03-01 01:09:32 +00:00
2012-09-28 21:48:18 +00:00
FramebufferManagerBase : : SetLastXfbWidth ( MAX_XFB_WIDTH ) ;
FramebufferManagerBase : : SetLastXfbHeight ( MAX_XFB_HEIGHT ) ;
2010-03-14 18:57:50 +00:00
2012-09-28 22:04:55 +00:00
UpdateDrawRectangle ( s_backbuffer_width , s_backbuffer_height ) ;
2011-01-02 23:13:29 +00:00
2010-06-09 15:33:01 +00:00
s_LastAA = g_ActiveConfig . iMultisampleMode ;
2011-01-07 19:23:57 +00:00
int SupersampleCoeficient = ( s_LastAA % 3 ) + 1 ;
2010-05-19 03:15:36 +00:00
2010-11-18 02:21:26 +00:00
s_LastEFBScale = g_ActiveConfig . iEFBScale ;
2012-09-28 22:19:28 +00:00
CalculateTargetSize ( s_backbuffer_width , s_backbuffer_height , SupersampleCoeficient ) ;
2011-01-02 23:13:29 +00:00
// Make sure to use valid texture sizes
2011-05-12 02:14:45 +00:00
D3D : : FixTextureSize ( s_target_width , s_target_height ) ;
2011-01-02 23:13:29 +00:00
2010-04-03 22:22:55 +00:00
// We're not using fixed function.
2009-09-03 19:24:16 +00:00
// Let's just set the matrices to identity to be sure.
2009-02-28 22:10:38 +00:00
D3DXMATRIX mtx ;
D3DXMatrixIdentity ( & mtx ) ;
D3D : : dev - > SetTransform ( D3DTS_VIEW , & mtx ) ;
D3D : : dev - > SetTransform ( D3DTS_WORLD , & mtx ) ;
2009-09-13 17:46:33 +00:00
SetupDeviceObjects ( ) ;
2009-09-03 20:37:35 +00:00
2009-09-15 21:05:31 +00:00
for ( int stage = 0 ; stage < 8 ; stage + + )
2011-01-31 13:17:57 +00:00
D3D : : SetSamplerState ( stage , D3DSAMP_MAXANISOTROPY , 1 < < g_ActiveConfig . iMaxAnisotropy ) ;
2010-01-17 17:44:09 +00:00
2009-11-08 20:35:11 +00:00
D3DVIEWPORT9 vp ;
vp . X = 0 ;
vp . Y = 0 ;
vp . Width = s_backbuffer_width ;
vp . Height = s_backbuffer_height ;
vp . MinZ = 0.0f ;
Well this commit has 2 parts:
first part if fixing, fixed, i thing, the flickering that everyone has reported, at least in my case i only have flickering in the one texture in one game and now is fixed. The other fix is not for an reported issue, is more a correctness fix, running dolphin with pix to review debug errors, result in a ton of warnings and error, now with this commit, at least for ati, there no more error or warnings, this means, correct management and state change, no accurate emulation, for this still a lot of work to do.
for this part of the commit please give me feedback and let me know of remaining issues
Te second part is the partial implementation of efb to ram copy in d3d, this won't brake anything because is commented but i commit this to ask for help from ector and donko in some errors remaining in the implementation related to differences between opengl an d3d.
if you want to test this you have to uncomment line 150 to 155 of bpstruct.cpp
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4594 8ced0084-cf51-0410-be5f-012b33b47a6e
2009-11-20 18:46:30 +00:00
vp . MaxZ = 1.0f ;
2009-11-08 20:35:11 +00:00
D3D : : dev - > SetViewport ( & vp ) ;
2009-09-13 17:46:33 +00:00
D3D : : dev - > Clear ( 0 , NULL , D3DCLEAR_TARGET , 0x0 , 0 , 0 ) ;
2009-11-08 20:35:11 +00:00
2010-11-14 23:31:53 +00:00
D3D : : dev - > SetRenderTarget ( 0 , FramebufferManager : : GetEFBColorRTSurface ( ) ) ;
D3D : : dev - > SetDepthStencilSurface ( FramebufferManager : : GetEFBDepthRTSurface ( ) ) ;
2011-05-12 02:14:45 +00:00
vp . X = 0 ;
vp . Y = 0 ;
2009-11-08 20:35:11 +00:00
vp . Width = s_target_width ;
vp . Height = s_target_height ;
D3D : : dev - > SetViewport ( & vp ) ;
2011-01-06 16:05:11 +00:00
D3D : : dev - > Clear ( 0 , NULL , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB ( 0 , 0 , 0 ) , 1.0f , 0 ) ;
2009-09-13 17:46:33 +00:00
D3D : : BeginFrame ( ) ;
2009-10-30 04:14:43 +00:00
D3D : : SetRenderState ( D3DRS_SCISSORTESTENABLE , true ) ;
2010-07-09 20:56:16 +00:00
D3D : : dev - > CreateOffscreenPlainSurface ( s_backbuffer_width , s_backbuffer_height , D3DFMT_X8R8G8B8 , D3DPOOL_SYSTEMMEM , & ScreenShootMEMSurface , NULL ) ;
2012-11-12 22:37:08 +00:00
D3D : : SetRenderState ( D3DRS_POINTSCALEENABLE , false ) ;
m_fMaxPointSize = D3D : : GetCaps ( ) . MaxPointSize ;
2013-04-01 17:23:48 +00:00
// Handle VSync on/off
s_vsync = g_ActiveConfig . IsVSync ( ) ;
2008-12-08 05:25:12 +00:00
}
2010-11-18 02:21:26 +00:00
Renderer : : ~ Renderer ( )
2008-12-08 05:25:12 +00:00
{
2009-09-13 17:46:33 +00:00
TeardownDeviceObjects ( ) ;
2008-12-08 05:25:12 +00:00
D3D : : EndFrame ( ) ;
2009-09-20 03:29:43 +00:00
D3D : : Present ( ) ;
2008-12-08 05:25:12 +00:00
D3D : : Close ( ) ;
2010-02-25 06:12:35 +00:00
2010-11-18 02:21:26 +00:00
delete [ ] st ;
2010-01-29 07:44:21 +00:00
}
2009-09-03 19:42:45 +00:00
void Renderer : : RenderText ( const char * text , int left , int top , u32 color )
2008-12-08 05:25:12 +00:00
{
2010-11-07 10:11:58 +00:00
D3D : : font . DrawTextScaled ( ( float ) left , ( float ) top , 20 , 20 , 0.0f , color , text ) ;
2008-12-08 05:25:12 +00:00
}
2009-09-03 21:56:08 +00:00
TargetRectangle Renderer : : ConvertEFBRectangle ( const EFBRectangle & rc )
{
2010-09-30 15:24:34 +00:00
TargetRectangle result ;
2011-05-12 02:14:45 +00:00
result . left = EFBToScaledX ( rc . left ) ;
result . top = EFBToScaledY ( rc . top ) ;
result . right = EFBToScaledX ( rc . right ) ;
result . bottom = EFBToScaledY ( rc . bottom ) ;
2009-09-03 21:56:08 +00:00
return result ;
}
2010-11-18 02:21:26 +00:00
}
2013-02-27 01:47:48 +00:00
void formatBufferDump ( const u8 * in , u8 * out , int w , int h , int p )
2009-03-28 21:07:16 +00:00
{
2009-09-03 21:56:08 +00:00
for ( int y = 0 ; y < h ; y + + )
{
2013-02-27 01:47:48 +00:00
auto line = in + ( h - y - 1 ) * p ;
2009-09-03 21:56:08 +00:00
for ( int x = 0 ; x < w ; x + + )
{
2009-03-28 21:07:16 +00:00
memcpy ( out , line , 3 ) ;
out + = 3 ;
line + = 4 ;
2013-04-15 20:28:55 +00:00
}
2009-03-28 21:07:16 +00:00
}
}
2010-11-18 02:21:26 +00:00
namespace DX9
{
2009-09-15 19:53:22 +00:00
// With D3D, we have to resize the backbuffer if the window changed
// size.
2010-11-18 02:21:26 +00:00
bool Renderer : : CheckForResize ( )
2009-09-15 19:53:22 +00:00
{
while ( EmuWindow : : IsSizing ( ) )
Sleep ( 10 ) ;
2010-09-28 02:15:02 +00:00
2010-01-28 04:30:07 +00:00
if ( EmuWindow : : GetParentWnd ( ) )
{
// Re-stretch window to parent window size again, if it has a parent window.
RECT rcParentWindow ;
GetWindowRect ( EmuWindow : : GetParentWnd ( ) , & rcParentWindow ) ;
int width = rcParentWindow . right - rcParentWindow . left ;
int height = rcParentWindow . bottom - rcParentWindow . top ;
2010-11-18 02:21:26 +00:00
if ( width ! = Renderer : : GetBackbufferWidth ( ) | | height ! = Renderer : : GetBackbufferHeight ( ) )
2010-07-06 13:14:51 +00:00
MoveWindow ( EmuWindow : : GetWnd ( ) , 0 , 0 , width , height , FALSE ) ;
2010-01-28 04:30:07 +00:00
}
2010-11-18 02:21:26 +00:00
2009-09-15 19:53:22 +00:00
RECT rcWindow ;
GetClientRect ( EmuWindow : : GetWnd ( ) , & rcWindow ) ;
int client_width = rcWindow . right - rcWindow . left ;
int client_height = rcWindow . bottom - rcWindow . top ;
2010-09-28 02:15:02 +00:00
// Sanity check
2010-11-18 02:21:26 +00:00
if ( ( client_width ! = Renderer : : GetBackbufferWidth ( ) | |
client_height ! = Renderer : : GetBackbufferHeight ( ) ) & &
2009-09-15 19:53:22 +00:00
client_width > = 4 & & client_height > = 4 )
{
TeardownDeviceObjects ( ) ;
2010-07-06 13:14:51 +00:00
D3D : : Reset ( ) ;
2009-09-15 19:53:22 +00:00
s_backbuffer_width = D3D : : GetBackBufferWidth ( ) ;
s_backbuffer_height = D3D : : GetBackBufferHeight ( ) ;
2010-07-09 20:56:16 +00:00
if ( ScreenShootMEMSurface )
ScreenShootMEMSurface - > Release ( ) ;
2010-11-18 02:21:26 +00:00
D3D : : dev - > CreateOffscreenPlainSurface ( Renderer : : GetBackbufferWidth ( ) , Renderer : : GetBackbufferHeight ( ) ,
D3DFMT_X8R8G8B8 , D3DPOOL_SYSTEMMEM , & ScreenShootMEMSurface , NULL ) ;
2009-09-15 19:53:22 +00:00
2010-11-18 02:21:26 +00:00
return true ;
2010-03-14 18:57:50 +00:00
}
2010-11-18 02:21:26 +00:00
return false ;
2008-12-08 05:25:12 +00:00
}
2011-09-05 20:04:28 +00:00
void Renderer : : SetScissorRect ( const TargetRectangle & rc )
2008-12-08 05:25:12 +00:00
{
2011-09-05 20:04:28 +00:00
D3D : : dev - > SetScissorRect ( rc . AsRECT ( ) ) ;
2009-09-03 19:42:45 +00:00
}
2010-09-28 02:15:02 +00:00
void Renderer : : SetColorMask ( )
2009-09-03 19:42:45 +00:00
{
2010-12-20 16:57:29 +00:00
// Only enable alpha channel if it's supported by the current EFB format
2009-09-13 08:21:35 +00:00
DWORD color_mask = 0 ;
2013-01-08 16:23:01 +00:00
if ( bpmem . alpha_test . TestResult ( ) ! = AlphaTest : : FAIL )
{
if ( bpmem . blendmode . alphaupdate & & ( bpmem . zcontrol . pixel_format = = PIXELFMT_RGBA6_Z24 ) )
color_mask = D3DCOLORWRITEENABLE_ALPHA ;
if ( bpmem . blendmode . colorupdate )
color_mask | = D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE ;
}
2009-09-13 08:21:35 +00:00
D3D : : SetRenderState ( D3DRS_COLORWRITEENABLE , color_mask ) ;
2008-12-08 05:25:12 +00:00
}
2010-10-24 19:52:52 +00:00
// This function allows the CPU to directly access the EFB.
// There are EFB peeks (which will read the color or depth of a pixel)
// and EFB pokes (which will change the color or depth of a pixel).
//
// The behavior of EFB peeks can only be modified by:
// - GX_PokeAlphaRead
// The behavior of EFB pokes can be modified by:
// - GX_PokeAlphaMode (TODO)
// - GX_PokeAlphaUpdate (TODO)
// - GX_PokeBlendMode (TODO)
// - GX_PokeColorUpdate (TODO)
// - GX_PokeDither (TODO)
// - GX_PokeDstAlpha (TODO)
// - GX_PokeZMode (TODO)
2010-10-22 19:40:05 +00:00
u32 Renderer : : AccessEFB ( EFBAccessType type , u32 x , u32 y , u32 poke_data )
2009-09-04 17:29:16 +00:00
{
2010-01-17 17:44:09 +00:00
if ( ! g_ActiveConfig . bEFBAccessEnable )
2009-12-28 19:13:06 +00:00
return 0 ;
2010-10-22 19:40:05 +00:00
if ( type = = POKE_Z )
2010-07-16 21:51:35 +00:00
{
static bool alert_only_once = true ;
if ( ! alert_only_once ) return 0 ;
2010-10-22 19:40:05 +00:00
PanicAlert ( " EFB: Poke Z not implemented (tried to poke z value %#x at (%d,%d)) " , poke_data , x , y ) ;
2010-07-16 21:51:35 +00:00
alert_only_once = false ;
return 0 ;
}
2011-01-04 12:56:52 +00:00
// if depth textures aren't supported by the hardware, just return
if ( type = = PEEK_Z )
if ( FramebufferManager : : GetEFBDepthTexture ( ) = = NULL )
return 0 ;
2010-10-22 19:40:05 +00:00
// We're using three surfaces here:
// - pEFBSurf: EFB Surface. Source surface when peeking, destination surface when poking.
// - pBufferRT: A render target surface. When peeking, we render a textured quad to this surface.
// - pSystemBuf: An offscreen surface. Used to retrieve the pixel data from pBufferRT.
LPDIRECT3DSURFACE9 pEFBSurf , pBufferRT , pSystemBuf ;
if ( type = = PEEK_Z | | type = = POKE_Z )
{
2010-11-14 23:31:53 +00:00
pEFBSurf = FramebufferManager : : GetEFBDepthRTSurface ( ) ;
pBufferRT = FramebufferManager : : GetEFBDepthReadSurface ( ) ;
pSystemBuf = FramebufferManager : : GetEFBDepthOffScreenRTSurface ( ) ;
2010-10-22 19:40:05 +00:00
}
else //if(type == PEEK_COLOR || type == POKE_COLOR)
{
2010-11-14 23:31:53 +00:00
pEFBSurf = FramebufferManager : : GetEFBColorRTSurface ( ) ;
pBufferRT = FramebufferManager : : GetEFBColorReadSurface ( ) ;
pSystemBuf = FramebufferManager : : GetEFBColorOffScreenRTSurface ( ) ;
2010-10-22 19:40:05 +00:00
}
2009-12-28 19:13:06 +00:00
2010-07-06 13:14:51 +00:00
// Buffer not found alert
2010-10-22 19:40:05 +00:00
if ( ! pEFBSurf ) {
2009-10-06 14:24:10 +00:00
PanicAlert ( " No %s! " , ( type = = PEEK_Z | | type = = POKE_Z ) ? " Z-Buffer " : " Color EFB " ) ;
return 0 ;
}
2010-10-22 19:40:05 +00:00
// Convert EFB dimensions to the ones of our render target
2009-09-04 17:29:16 +00:00
EFBRectangle efbPixelRc ;
efbPixelRc . left = x ;
efbPixelRc . top = y ;
efbPixelRc . right = x + 1 ;
efbPixelRc . bottom = y + 1 ;
2010-09-30 15:24:34 +00:00
TargetRectangle targetPixelRc = ConvertEFBRectangle ( efbPixelRc ) ;
2009-09-04 17:29:16 +00:00
2009-10-03 02:12:24 +00:00
HRESULT hr ;
RECT RectToLock ;
RectToLock . bottom = targetPixelRc . bottom ;
RectToLock . left = targetPixelRc . left ;
RectToLock . right = targetPixelRc . right ;
2009-11-22 02:37:00 +00:00
RectToLock . top = targetPixelRc . top ;
2010-01-17 17:44:09 +00:00
if ( type = = PEEK_Z )
2009-11-08 20:35:11 +00:00
{
2011-01-06 02:24:03 +00:00
// TODO: why is D3DFMT_D24X8 singled out here? why not D3DFMT_D24X4S4/D24S8/D24FS8/D32/D16/D15S1 too, or none of them?
2010-11-14 23:31:53 +00:00
if ( FramebufferManager : : GetEFBDepthRTSurfaceFormat ( ) = = D3DFMT_D24X8 )
2010-10-22 19:40:05 +00:00
return 0 ;
2009-11-22 02:37:00 +00:00
RECT PixelRect ;
PixelRect . bottom = 4 ;
PixelRect . left = 0 ;
PixelRect . right = 4 ;
PixelRect . top = 0 ;
RectToLock . bottom + = 2 ;
RectToLock . right + = 1 ;
RectToLock . top - = 1 ;
RectToLock . left - = 2 ;
2010-01-17 17:44:09 +00:00
if ( ( RectToLock . bottom - RectToLock . top ) > 4 )
2009-11-22 02:37:00 +00:00
RectToLock . bottom - - ;
2010-01-17 17:44:09 +00:00
if ( ( RectToLock . right - RectToLock . left ) > 4 )
2009-11-22 02:37:00 +00:00
RectToLock . left + + ;
2010-09-28 02:15:02 +00:00
2010-07-06 13:14:51 +00:00
ResetAPIState ( ) ; // Reset any game specific settings
2010-10-22 19:40:05 +00:00
D3D : : dev - > SetDepthStencilSurface ( NULL ) ;
D3D : : dev - > SetRenderTarget ( 0 , pBufferRT ) ;
2009-11-22 02:37:00 +00:00
// Stretch picture with increased internal resolution
2010-10-22 19:40:05 +00:00
D3DVIEWPORT9 vp ;
2009-11-22 02:37:00 +00:00
vp . X = 0 ;
vp . Y = 0 ;
vp . Width = 4 ;
vp . Height = 4 ;
vp . MinZ = 0.0f ;
vp . MaxZ = 1.0f ;
2010-10-22 19:40:05 +00:00
D3D : : dev - > SetViewport ( & vp ) ;
2011-01-07 19:23:57 +00:00
float colmat [ 28 ] = { 0.0f } ;
2009-11-22 02:37:00 +00:00
colmat [ 0 ] = colmat [ 5 ] = colmat [ 10 ] = 1.0f ;
2011-01-07 19:23:57 +00:00
PixelShaderManager : : SetColorMatrix ( colmat ) ; // set transformation
2010-11-14 23:31:53 +00:00
LPDIRECT3DTEXTURE9 read_texture = FramebufferManager : : GetEFBDepthTexture ( ) ;
2009-11-22 02:37:00 +00:00
2010-07-06 13:14:51 +00:00
D3D : : ChangeSamplerState ( 0 , D3DSAMP_MINFILTER , D3DTEXF_POINT ) ;
2009-11-22 02:37:00 +00:00
2010-12-19 20:59:23 +00:00
D3DFORMAT bformat = FramebufferManager : : GetEFBDepthRTSurfaceFormat ( ) ;
2010-02-08 23:23:04 +00:00
D3D : : drawShadedTexQuad (
2010-10-22 19:40:05 +00:00
read_texture ,
& RectToLock ,
2011-05-12 02:14:45 +00:00
Renderer : : GetTargetWidth ( ) ,
Renderer : : GetTargetHeight ( ) ,
2010-10-22 19:40:05 +00:00
4 , 4 ,
2011-01-06 02:24:03 +00:00
PixelShaderCache : : GetDepthMatrixProgram ( 0 , bformat ! = FOURCC_RAWZ ) ,
2010-06-05 00:01:18 +00:00
VertexShaderCache : : GetSimpleVertexShader ( 0 ) ) ;
2009-11-22 02:37:00 +00:00
D3D : : RefreshSamplerState ( 0 , D3DSAMP_MINFILTER ) ;
2010-11-14 23:31:53 +00:00
D3D : : dev - > SetRenderTarget ( 0 , FramebufferManager : : GetEFBColorRTSurface ( ) ) ;
D3D : : dev - > SetDepthStencilSurface ( FramebufferManager : : GetEFBDepthRTSurface ( ) ) ;
2009-11-22 02:37:00 +00:00
RestoreAPIState ( ) ;
2010-10-22 19:40:05 +00:00
// Retrieve the pixel data to the local memory buffer
2009-11-22 02:37:00 +00:00
RectToLock . bottom = 4 ;
RectToLock . left = 0 ;
RectToLock . right = 4 ;
RectToLock . top = 0 ;
2010-10-22 19:40:05 +00:00
D3D : : dev - > GetRenderTargetData ( pBufferRT , pSystemBuf ) ;
// EFB data successfully retrieved, now get the pixel data
D3DLOCKED_RECT drect ;
pSystemBuf - > LockRect ( & drect , & RectToLock , D3DLOCK_READONLY ) ;
2011-01-10 21:28:02 +00:00
u32 z = ( ( u32 * ) drect . pBits ) [ 6 ] ; // 24 bit depth value
2010-10-22 19:40:05 +00:00
pSystemBuf - > UnlockRect ( ) ;
2011-01-10 21:28:02 +00:00
// if Z is in 16 bit format you must return a 16 bit integer
if ( bpmem . zcontrol . pixel_format = = PIXELFMT_RGB565_Z16 ) {
z > > = 8 ;
2010-12-27 03:18:01 +00:00
}
2011-01-10 21:28:02 +00:00
2010-10-22 19:40:05 +00:00
return z ;
2009-11-22 02:37:00 +00:00
}
2010-10-22 19:40:05 +00:00
else if ( type = = PEEK_COLOR )
2009-11-22 02:37:00 +00:00
{
2013-04-07 21:11:29 +00:00
// We can't directly StretchRect to System buf because is not supported by all implementations
2013-04-01 17:23:48 +00:00
// this is the only safe path that works in most cases
2010-10-22 19:40:05 +00:00
hr = D3D : : dev - > StretchRect ( pEFBSurf , & RectToLock , pBufferRT , NULL , D3DTEXF_NONE ) ;
D3D : : dev - > GetRenderTargetData ( pBufferRT , pSystemBuf ) ;
// EFB data successfully retrieved, now get the pixel data
2009-11-10 12:45:03 +00:00
RectToLock . bottom = 1 ;
RectToLock . left = 0 ;
RectToLock . right = 1 ;
RectToLock . top = 0 ;
2011-01-10 21:28:02 +00:00
2010-10-22 19:40:05 +00:00
D3DLOCKED_RECT drect ;
pSystemBuf - > LockRect ( & drect , & RectToLock , D3DLOCK_READONLY ) ;
2010-10-24 19:52:52 +00:00
u32 ret = ( ( u32 * ) drect . pBits ) [ 0 ] ;
2010-10-22 19:40:05 +00:00
pSystemBuf - > UnlockRect ( ) ;
2010-10-24 19:52:52 +00:00
// check what to do with the alpha channel (GX_PokeAlphaRead)
PixelEngine : : UPEAlphaReadReg alpha_read_mode ;
2011-01-07 19:51:28 +00:00
PixelEngine : : Read16 ( ( u16 & ) alpha_read_mode , PE_ALPHAREAD ) ;
2011-01-10 21:28:02 +00:00
2010-12-27 03:18:01 +00:00
if ( bpmem . zcontrol . pixel_format = = PIXELFMT_RGBA6_Z24 )
{
ret = RGBA8ToRGBA6ToRGBA8 ( ret ) ;
}
else if ( bpmem . zcontrol . pixel_format = = PIXELFMT_RGB565_Z16 )
{
2010-12-27 18:09:03 +00:00
ret = RGBA8ToRGB565ToRGBA8 ( ret ) ;
}
2010-12-27 03:18:01 +00:00
if ( bpmem . zcontrol . pixel_format ! = PIXELFMT_RGBA6_Z24 )
{
ret | = 0xFF000000 ;
}
2011-01-10 21:28:02 +00:00
2010-10-24 19:52:52 +00:00
if ( alpha_read_mode . ReadMode = = 2 ) return ret ; // GX_READ_NONE
else if ( alpha_read_mode . ReadMode = = 1 ) return ( ret | 0xFF000000 ) ; // GX_READ_FF
2010-12-27 03:18:01 +00:00
else return ( ret & 0x00FFFFFF ) ; // GX_READ_00
2009-10-10 23:36:18 +00:00
}
2010-10-22 19:40:05 +00:00
else //if(type == POKE_COLOR)
2010-09-28 02:15:02 +00:00
{
2010-10-22 19:40:05 +00:00
// TODO: Speed this up by batching pokes?
ResetAPIState ( ) ;
2012-02-20 10:51:40 +00:00
D3D : : drawColorQuad ( poke_data ,
2011-05-12 02:14:45 +00:00
( float ) RectToLock . left * 2.f / ( float ) Renderer : : GetTargetWidth ( ) - 1.f ,
- ( float ) RectToLock . top * 2.f / ( float ) Renderer : : GetTargetHeight ( ) + 1.f ,
( float ) RectToLock . right * 2.f / ( float ) Renderer : : GetTargetWidth ( ) - 1.f ,
- ( float ) RectToLock . bottom * 2.f / ( float ) Renderer : : GetTargetHeight ( ) + 1.f ) ;
2010-10-22 19:40:05 +00:00
RestoreAPIState ( ) ;
return 0 ;
2009-09-04 17:29:16 +00:00
}
}
2011-05-12 02:14:45 +00:00
// Viewport correction:
// Say you want a viewport at (ix, iy) with size (iw, ih),
// but your viewport must be clamped at (ax, ay) with size (aw, ah).
// Just multiply the projection matrix with the following to get the same
// effect:
// [ (iw/aw) 0 0 ((iw - 2*(ax-ix)) / aw - 1) ]
// [ 0 (ih/ah) 0 ((-ih + 2*(ay-iy)) / ah + 1) ]
// [ 0 0 1 0 ]
// [ 0 0 0 1 ]
static void ViewportCorrectionMatrix ( Matrix44 & result ,
float ix , float iy , float iw , float ih , // Intended viewport (x, y, width, height)
float ax , float ay , float aw , float ah ) // Actual viewport (x, y, width, height)
{
Matrix44 : : LoadIdentity ( result ) ;
if ( aw = = 0.f | | ah = = 0.f )
return ;
result . data [ 4 * 0 + 0 ] = iw / aw ;
result . data [ 4 * 0 + 3 ] = ( iw - 2.f * ( ax - ix ) ) / aw - 1.f ;
result . data [ 4 * 1 + 1 ] = ih / ah ;
result . data [ 4 * 1 + 3 ] = ( - ih + 2.f * ( ay - iy ) ) / ah + 1.f ;
}
2009-02-28 22:10:38 +00:00
// Called from VertexShaderManager
2011-05-12 02:14:45 +00:00
void Renderer : : UpdateViewport ( Matrix44 & vpCorrection )
2009-02-28 22:10:38 +00:00
{
2009-11-23 14:08:08 +00:00
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
2010-02-25 06:12:35 +00:00
// [0] = width/2
// [1] = height/2
// [2] = 16777215 * (farz - nearz)
// [3] = xorig + width/2 + 342
// [4] = yorig + height/2 + 342
// [5] = 16777215 * farz
2010-07-11 16:26:46 +00:00
2011-05-12 02:14:45 +00:00
int scissorXOff = bpmem . scissorOffset . x * 2 ;
int scissorYOff = bpmem . scissorOffset . y * 2 ;
2009-02-28 22:10:38 +00:00
2010-12-10 15:54:14 +00:00
// TODO: ceil, floor or just cast to int?
2011-05-12 02:14:45 +00:00
int intendedX = EFBToScaledX ( ( int ) ceil ( xfregs . viewport . xOrig - xfregs . viewport . wd - scissorXOff ) ) ;
int intendedY = EFBToScaledY ( ( int ) ceil ( xfregs . viewport . yOrig + xfregs . viewport . ht - scissorYOff ) ) ;
int intendedWd = EFBToScaledX ( ( int ) ceil ( 2.0f * xfregs . viewport . wd ) ) ;
int intendedHt = EFBToScaledY ( ( int ) ceil ( - 2.0f * xfregs . viewport . ht ) ) ;
if ( intendedWd < 0 )
2009-11-23 14:08:08 +00:00
{
2011-05-12 02:14:45 +00:00
intendedX + = intendedWd ;
intendedWd = - intendedWd ;
2009-11-23 14:08:08 +00:00
}
2011-05-12 02:14:45 +00:00
if ( intendedHt < 0 )
2009-11-23 14:08:08 +00:00
{
2011-05-12 02:14:45 +00:00
intendedY + = intendedHt ;
intendedHt = - intendedHt ;
2009-11-23 14:08:08 +00:00
}
2011-05-12 02:14:45 +00:00
// In D3D, the viewport rectangle must fit within the render target.
int X = intendedX ;
2010-07-06 13:14:51 +00:00
if ( X < 0 )
2010-02-03 22:19:00 +00:00
X = 0 ;
2011-05-12 02:14:45 +00:00
int Y = intendedY ;
2010-07-06 13:14:51 +00:00
if ( Y < 0 )
2010-02-03 22:19:00 +00:00
Y = 0 ;
2011-05-12 02:14:45 +00:00
int Wd = intendedWd ;
if ( X + Wd > GetTargetWidth ( ) )
Wd = GetTargetWidth ( ) - X ;
int Ht = intendedHt ;
if ( Y + Ht > GetTargetHeight ( ) )
Ht = GetTargetHeight ( ) - Y ;
// If GX viewport is off the render target, we must clamp our viewport
// within the bounds. Use the correction matrix to compensate.
ViewportCorrectionMatrix ( vpCorrection ,
2012-12-23 07:01:58 +00:00
( float ) intendedX , ( float ) intendedY , ( float ) intendedWd , ( float ) intendedHt ,
( float ) X , ( float ) Y , ( float ) Wd , ( float ) Ht ) ;
2010-11-18 02:21:26 +00:00
D3DVIEWPORT9 vp ;
Well this commit has 2 parts:
first part if fixing, fixed, i thing, the flickering that everyone has reported, at least in my case i only have flickering in the one texture in one game and now is fixed. The other fix is not for an reported issue, is more a correctness fix, running dolphin with pix to review debug errors, result in a ton of warnings and error, now with this commit, at least for ati, there no more error or warnings, this means, correct management and state change, no accurate emulation, for this still a lot of work to do.
for this part of the commit please give me feedback and let me know of remaining issues
Te second part is the partial implementation of efb to ram copy in d3d, this won't brake anything because is commented but i commit this to ask for help from ector and donko in some errors remaining in the implementation related to differences between opengl an d3d.
if you want to test this you have to uncomment line 150 to 155 of bpstruct.cpp
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4594 8ced0084-cf51-0410-be5f-012b33b47a6e
2009-11-20 18:46:30 +00:00
vp . X = X ;
vp . Y = Y ;
2011-05-12 02:14:45 +00:00
vp . Width = Wd ;
vp . Height = Ht ;
2013-04-15 20:28:55 +00:00
2010-07-06 13:14:51 +00:00
// Some games set invalids values for z min and z max so fix them to the max an min alowed and let the shaders do this work
2011-04-11 01:49:32 +00:00
vp . MinZ = 0.0f ; // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f;
vp . MaxZ = 1.0f ; // xfregs.viewport.farZ / 16777216.0f;
2009-02-28 22:10:38 +00:00
D3D : : dev - > SetViewport ( & vp ) ;
2009-09-02 04:10:40 +00:00
}
2009-09-20 03:29:43 +00:00
2010-12-19 22:00:25 +00:00
void Renderer : : ClearScreen ( const EFBRectangle & rc , bool colorEnable , bool alphaEnable , bool zEnable , u32 color , u32 z )
2010-07-06 13:14:51 +00:00
{
2010-11-01 19:13:50 +00:00
// Reset rendering pipeline while keeping color masks and depth buffer settings
ResetAPIState ( ) ;
2010-12-20 16:57:29 +00:00
DWORD color_mask = 0 ;
if ( alphaEnable )
color_mask = D3DCOLORWRITEENABLE_ALPHA ;
if ( colorEnable )
color_mask | = D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE ;
D3D : : ChangeRenderState ( D3DRS_COLORWRITEENABLE , color_mask ) ;
if ( zEnable )
{
D3D : : ChangeRenderState ( D3DRS_ZENABLE , TRUE ) ;
D3D : : ChangeRenderState ( D3DRS_ZWRITEENABLE , TRUE ) ;
2010-11-01 19:13:50 +00:00
D3D : : ChangeRenderState ( D3DRS_ZFUNC , D3DCMP_ALWAYS ) ;
2010-12-20 16:57:29 +00:00
}
else
2013-04-15 20:28:55 +00:00
{
2010-12-20 16:57:29 +00:00
D3D : : ChangeRenderState ( D3DRS_ZENABLE , FALSE ) ;
2013-04-15 20:40:48 +00:00
}
2010-11-01 19:13:50 +00:00
2010-12-10 15:54:14 +00:00
// Update the viewport for clearing the target EFB rect
2010-09-30 15:24:34 +00:00
TargetRectangle targetRc = ConvertEFBRectangle ( rc ) ;
2010-02-25 06:12:35 +00:00
D3DVIEWPORT9 vp ;
2010-06-15 21:19:09 +00:00
vp . X = targetRc . left ;
2010-07-06 13:14:51 +00:00
vp . Y = targetRc . top ;
2010-06-15 21:19:09 +00:00
vp . Width = targetRc . GetWidth ( ) ;
vp . Height = targetRc . GetHeight ( ) ;
2009-11-22 02:37:00 +00:00
vp . MinZ = 0.0 ;
vp . MaxZ = 1.0 ;
2010-07-06 13:14:51 +00:00
D3D : : dev - > SetViewport ( & vp ) ;
2012-02-20 10:51:40 +00:00
D3D : : drawClearQuad ( color , ( z & 0xFFFFFF ) / float ( 0xFFFFFF ) , PixelShaderCache : : GetClearProgram ( ) , VertexShaderCache : : GetClearVertexShader ( ) ) ;
2010-11-01 19:13:50 +00:00
RestoreAPIState ( ) ;
2009-10-02 21:23:56 +00:00
}
2010-12-27 21:56:20 +00:00
void Renderer : : ReinterpretPixelData ( unsigned int convtype )
{
RECT source ;
2011-05-12 02:14:45 +00:00
SetRect ( & source , 0 , 0 , g_renderer - > GetTargetWidth ( ) , g_renderer - > GetTargetHeight ( ) ) ;
2010-12-27 21:56:20 +00:00
LPDIRECT3DPIXELSHADER9 pixel_shader ;
if ( convtype = = 0 ) pixel_shader = PixelShaderCache : : ReinterpRGB8ToRGBA6 ( ) ;
else if ( convtype = = 2 ) pixel_shader = PixelShaderCache : : ReinterpRGBA6ToRGB8 ( ) ;
else
{
2012-01-06 12:45:51 +00:00
ERROR_LOG ( VIDEO , " Trying to reinterpret pixel data with unsupported conversion type %d " , convtype ) ;
2010-12-27 21:56:20 +00:00
return ;
}
// convert data and set the target texture as our new EFB
g_renderer - > ResetAPIState ( ) ;
D3D : : dev - > SetRenderTarget ( 0 , FramebufferManager : : GetEFBColorReinterpretSurface ( ) ) ;
2011-01-23 15:29:57 +00:00
D3DVIEWPORT9 vp ;
vp . X = 0 ;
vp . Y = 0 ;
2011-05-12 02:14:45 +00:00
vp . Width = g_renderer - > GetTargetWidth ( ) ;
vp . Height = g_renderer - > GetTargetHeight ( ) ;
2011-01-23 15:29:57 +00:00
vp . MinZ = 0.0 ;
vp . MaxZ = 1.0 ;
D3D : : dev - > SetViewport ( & vp ) ;
D3D : : ChangeSamplerState ( 0 , D3DSAMP_MINFILTER , D3DTEXF_POINT ) ;
2011-05-12 02:14:45 +00:00
D3D : : drawShadedTexQuad ( FramebufferManager : : GetEFBColorTexture ( ) , & source ,
g_renderer - > GetTargetWidth ( ) , g_renderer - > GetTargetHeight ( ) ,
g_renderer - > GetTargetWidth ( ) , g_renderer - > GetTargetHeight ( ) ,
pixel_shader , VertexShaderCache : : GetSimpleVertexShader ( 0 ) ) ;
2010-12-27 21:56:20 +00:00
FramebufferManager : : SwapReinterpretTexture ( ) ;
2011-01-23 15:29:57 +00:00
D3D : : RefreshSamplerState ( 0 , D3DSAMP_MINFILTER ) ;
2010-12-27 21:56:20 +00:00
g_renderer - > RestoreAPIState ( ) ;
}
2009-10-10 23:36:18 +00:00
void Renderer : : SetBlendMode ( bool forceUpdate )
2010-07-06 13:14:51 +00:00
{
2013-01-13 22:35:07 +00:00
// Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel
// Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1.
bool target_has_alpha = bpmem . zcontrol . pixel_format = = PIXELFMT_RGBA6_Z24 ;
2013-04-07 21:11:29 +00:00
//bDstAlphaPass is taken into account because the ability to disable alpha composition is
//really useful for debugging shader and blending errors
2013-03-31 23:02:13 +00:00
bool use_DstAlpha = ! g_ActiveConfig . bDstAlphaPass & & bpmem . dstalpha . enable & & bpmem . blendmode . alphaupdate & & target_has_alpha ;
bool use_DualSource = use_DstAlpha & & g_ActiveConfig . backend_info . bSupportsDualSourceBlend ;
2013-01-13 22:35:07 +00:00
const D3DBLEND d3dSrcFactors [ 8 ] =
2013-04-15 20:28:55 +00:00
{
D3DBLEND_ZERO ,
D3DBLEND_ONE ,
D3DBLEND_DESTCOLOR ,
D3DBLEND_INVDESTCOLOR ,
2013-03-31 23:02:13 +00:00
( use_DualSource ) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA ,
( use_DualSource ) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA ,
2013-04-15 20:28:55 +00:00
( target_has_alpha ) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE ,
( target_has_alpha ) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO
} ;
2013-01-13 22:35:07 +00:00
const D3DBLEND d3dDestFactors [ 8 ] =
{
D3DBLEND_ZERO ,
D3DBLEND_ONE ,
2013-04-15 20:28:55 +00:00
D3DBLEND_SRCCOLOR ,
D3DBLEND_INVSRCCOLOR ,
2013-03-31 23:02:13 +00:00
( use_DualSource ) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA ,
( use_DualSource ) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA ,
2013-04-15 20:28:55 +00:00
( target_has_alpha ) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE ,
( target_has_alpha ) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO
} ;
2013-01-13 22:35:07 +00:00
2010-11-30 21:44:54 +00:00
if ( bpmem . blendmode . logicopenable & & ! forceUpdate )
2010-06-24 15:58:06 +00:00
{
2013-03-28 23:08:51 +00:00
D3D : : SetRenderState ( D3DRS_SEPARATEALPHABLENDENABLE , false ) ;
return ;
2010-07-06 13:14:51 +00:00
}
2013-03-28 23:08:51 +00:00
2013-03-29 03:41:36 +00:00
bool blend_enable = bpmem . blendmode . subtract | | bpmem . blendmode . blendenable ;
D3D : : SetRenderState ( D3DRS_ALPHABLENDENABLE , blend_enable ) ;
2013-03-31 23:02:13 +00:00
D3D : : SetRenderState ( D3DRS_SEPARATEALPHABLENDENABLE , blend_enable & & g_ActiveConfig . backend_info . bSupportsSeparateAlphaFunction ) ;
2013-03-29 03:41:36 +00:00
if ( blend_enable )
2013-04-15 20:28:55 +00:00
{
2013-03-28 23:08:51 +00:00
D3DBLENDOP op = D3DBLENDOP_ADD ;
u32 srcidx = bpmem . blendmode . srcfactor ;
u32 dstidx = bpmem . blendmode . dstfactor ;
if ( bpmem . blendmode . subtract )
2013-04-15 20:28:55 +00:00
{
2013-03-28 23:08:51 +00:00
op = D3DBLENDOP_REVSUBTRACT ;
srcidx = GX_BL_ONE ;
dstidx = GX_BL_ONE ;
2013-04-15 20:28:55 +00:00
}
2013-03-28 23:08:51 +00:00
D3D : : SetRenderState ( D3DRS_BLENDOP , op ) ;
D3D : : SetRenderState ( D3DRS_SRCBLEND , d3dSrcFactors [ srcidx ] ) ;
D3D : : SetRenderState ( D3DRS_DESTBLEND , d3dDestFactors [ dstidx ] ) ;
2013-03-31 23:02:13 +00:00
if ( g_ActiveConfig . backend_info . bSupportsSeparateAlphaFunction )
2010-06-24 15:58:06 +00:00
{
2013-03-31 23:02:13 +00:00
if ( use_DualSource )
{
op = D3DBLENDOP_ADD ;
srcidx = GX_BL_ONE ;
dstidx = GX_BL_ZERO ;
}
else
{
// we can't use D3DBLEND_DESTCOLOR or D3DBLEND_INVDESTCOLOR for source in alpha channel so use their alpha equivalent instead
if ( srcidx = = GX_BL_DSTCLR ) srcidx = GX_BL_DSTALPHA ;
if ( srcidx = = GX_BL_INVDSTCLR ) srcidx = GX_BL_INVDSTALPHA ;
// we can't use D3DBLEND_SRCCOLOR or D3DBLEND_INVSRCCOLOR for destination in alpha channel so use their alpha equivalent instead
if ( dstidx = = GX_BL_SRCCLR ) dstidx = GX_BL_SRCALPHA ;
if ( dstidx = = GX_BL_INVSRCCLR ) dstidx = GX_BL_INVSRCALPHA ;
}
D3D : : SetRenderState ( D3DRS_BLENDOPALPHA , op ) ;
D3D : : SetRenderState ( D3DRS_SRCBLENDALPHA , d3dSrcFactors [ srcidx ] ) ;
D3D : : SetRenderState ( D3DRS_DESTBLENDALPHA , d3dDestFactors [ dstidx ] ) ;
}
2013-03-28 23:08:51 +00:00
}
2009-10-10 23:36:18 +00:00
}
2009-10-02 21:23:56 +00:00
2010-11-18 02:21:26 +00:00
bool Renderer : : SaveScreenshot ( const std : : string & filename , const TargetRectangle & dst_rect )
{
HRESULT hr = D3D : : dev - > GetRenderTargetData ( D3D : : GetBackBufferSurface ( ) , ScreenShootMEMSurface ) ;
if ( FAILED ( hr ) )
{
PanicAlert ( " Error dumping surface data. " ) ;
return false ;
}
hr = PD3DXSaveSurfaceToFileA ( filename . c_str ( ) , D3DXIFF_PNG , ScreenShootMEMSurface , NULL , dst_rect . AsRECT ( ) ) ;
if ( FAILED ( hr ) )
{
PanicAlert ( " Error saving screen. " ) ;
return false ;
}
return true ;
}
2010-09-28 02:15:02 +00:00
// This function has the final picture. We adjust the aspect ratio here.
2010-12-27 03:18:01 +00:00
void Renderer : : Swap ( u32 xfbAddr , FieldType field , u32 fbWidth , u32 fbHeight , const EFBRectangle & rc , float Gamma )
2009-09-20 03:29:43 +00:00
{
2012-09-28 21:19:50 +00:00
if ( g_bSkipCurrentFrame | | ( ! XFBWrited & & ! g_ActiveConfig . RealXFBEnabled ( ) ) | | ! fbWidth | | ! fbHeight )
fixed fps limiting when using using virtual xfb, now fps = vps, in fact now real xfb is as fast as no using xfb, i'm thinking now that the correct thing is leave it enabled as default, and even remove the option.
the problem is one strange behavior i found, in opengl when xfb is enable, frame limit causes the frame rate to be limited exact half the correct speed, so if you choose auto and the game uses 30 fps you get 15 fps
so in opengl, you have to limit to the exact double of the game speed, 100 to pal games and 120 to ntsc.
in d3d this not happened every time, it just happen when you change some time consuming setting like changing the ssaa or resizing the window, in that case you have to disable and re enable frame limit to get the correct fps
to all the devs please if you can help me debug this, will give you a lot of thanks as i'm short in time to debug this error and is driving me crazy not to find the source of the problem.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5249 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-03-28 23:51:32 +00:00
{
2013-02-27 01:47:48 +00:00
if ( g_ActiveConfig . bDumpFrames & & ! frame_data . empty ( ) )
AVIDump : : AddFrame ( & frame_data [ 0 ] , fbWidth , fbHeight ) ;
2011-09-08 13:39:03 +00:00
2011-01-31 01:28:32 +00:00
Core : : Callback_VideoCopiedToXFB ( false ) ;
2010-03-14 18:57:50 +00:00
return ;
fixed fps limiting when using using virtual xfb, now fps = vps, in fact now real xfb is as fast as no using xfb, i'm thinking now that the correct thing is leave it enabled as default, and even remove the option.
the problem is one strange behavior i found, in opengl when xfb is enable, frame limit causes the frame rate to be limited exact half the correct speed, so if you choose auto and the game uses 30 fps you get 15 fps
so in opengl, you have to limit to the exact double of the game speed, 100 to pal games and 120 to ntsc.
in d3d this not happened every time, it just happen when you change some time consuming setting like changing the ssaa or resizing the window, in that case you have to disable and re enable frame limit to get the correct fps
to all the devs please if you can help me debug this, will give you a lot of thanks as i'm short in time to debug this error and is driving me crazy not to find the source of the problem.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5249 8ced0084-cf51-0410-be5f-012b33b47a6e
2010-03-28 23:51:32 +00:00
}
2010-09-28 02:15:02 +00:00
2010-04-14 13:57:16 +00:00
if ( field = = FIELD_LOWER ) xfbAddr - = fbWidth * 2 ;
2010-03-14 18:57:50 +00:00
u32 xfbCount = 0 ;
2010-11-18 02:21:26 +00:00
const XFBSourceBase * const * xfbSourceList = FramebufferManager : : GetXFBSource ( xfbAddr , fbWidth , fbHeight , xfbCount ) ;
2010-07-02 17:09:53 +00:00
if ( ( ! xfbSourceList | | xfbCount = = 0 ) & & g_ActiveConfig . bUseXFB & & ! g_ActiveConfig . bUseRealXFB )
2010-03-14 18:57:50 +00:00
{
2013-02-27 01:47:48 +00:00
if ( g_ActiveConfig . bDumpFrames & & ! frame_data . empty ( ) )
AVIDump : : AddFrame ( & frame_data [ 0 ] , fbWidth , fbHeight ) ;
2011-09-08 13:39:03 +00:00
2011-01-31 01:28:32 +00:00
Core : : Callback_VideoCopiedToXFB ( false ) ;
2010-03-14 18:57:50 +00:00
return ;
2010-07-06 13:14:51 +00:00
}
2010-03-14 18:57:50 +00:00
2010-09-30 15:24:34 +00:00
ResetAPIState ( ) ;
2010-11-18 02:21:26 +00:00
2010-09-23 02:17:48 +00:00
if ( g_ActiveConfig . bAnaglyphStereo )
{
2010-11-10 16:43:27 +00:00
static bool RightFrame = false ;
2010-09-23 02:17:48 +00:00
if ( RightFrame )
{
D3D : : SetRenderState ( D3DRS_COLORWRITEENABLE , D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN ) ;
VertexShaderManager : : ResetView ( ) ;
VertexShaderManager : : TranslateView ( - 0.001f * g_ActiveConfig . iAnaglyphStereoSeparation , 0.0f ) ;
2010-12-10 15:54:14 +00:00
VertexShaderManager : : RotateView ( - 0.0001f * g_ActiveConfig . iAnaglyphFocalAngle , 0.0f ) ;
2010-09-23 02:17:48 +00:00
RightFrame = false ;
}
else
{
D3D : : SetRenderState ( D3DRS_COLORWRITEENABLE , D3DCOLORWRITEENABLE_RED ) ;
VertexShaderManager : : ResetView ( ) ;
VertexShaderManager : : TranslateView ( 0.001f * g_ActiveConfig . iAnaglyphStereoSeparation , 0.0f ) ;
2010-12-10 15:54:14 +00:00
VertexShaderManager : : RotateView ( 0.0001f * g_ActiveConfig . iAnaglyphFocalAngle , 0.0f ) ;
2010-09-23 02:17:48 +00:00
RightFrame = true ;
}
}
2010-09-28 02:15:02 +00:00
// Prepare to copy the XFBs to our backbuffer
2010-03-14 18:57:50 +00:00
D3D : : dev - > SetDepthStencilSurface ( NULL ) ;
D3D : : dev - > SetRenderTarget ( 0 , D3D : : GetBackBufferSurface ( ) ) ;
2012-09-28 22:04:55 +00:00
UpdateDrawRectangle ( s_backbuffer_width , s_backbuffer_height ) ;
2010-03-14 18:57:50 +00:00
D3DVIEWPORT9 vp ;
2010-09-30 15:24:34 +00:00
// Clear full target screen (edges, borders etc)
2010-11-10 16:43:27 +00:00
if ( g_ActiveConfig . bAnaglyphStereo ) {
// use a clear quad to keep old red or blue/green data
vp . X = 0 ;
vp . Y = 0 ;
vp . Width = s_backbuffer_width ;
vp . Height = s_backbuffer_height ;
vp . MinZ = 0.0f ;
vp . MaxZ = 1.0f ;
D3D : : dev - > SetViewport ( & vp ) ;
2012-02-20 10:51:40 +00:00
D3D : : drawClearQuad ( 0 , 1.0 , PixelShaderCache : : GetClearProgram ( ) , VertexShaderCache : : GetClearVertexShader ( ) ) ;
2010-11-10 16:43:27 +00:00
}
else
{
D3D : : dev - > Clear ( 0 , NULL , D3DCLEAR_TARGET , D3DCOLOR_XRGB ( 0 , 0 , 0 ) , 1.0f , 0 ) ;
}
2010-03-14 18:57:50 +00:00
2012-09-28 22:04:55 +00:00
int X = GetTargetRectangle ( ) . left ;
int Y = GetTargetRectangle ( ) . top ;
int Width = GetTargetRectangle ( ) . right - GetTargetRectangle ( ) . left ;
int Height = GetTargetRectangle ( ) . bottom - GetTargetRectangle ( ) . top ;
2010-09-30 15:24:34 +00:00
2010-12-10 15:54:14 +00:00
// Sanity check
2010-03-14 18:57:50 +00:00
if ( X < 0 ) X = 0 ;
if ( Y < 0 ) Y = 0 ;
if ( X > s_backbuffer_width ) X = s_backbuffer_width ;
if ( Y > s_backbuffer_height ) Y = s_backbuffer_height ;
if ( Width < 0 ) Width = 0 ;
if ( Height < 0 ) Height = 0 ;
if ( Width > ( s_backbuffer_width - X ) ) Width = s_backbuffer_width - X ;
if ( Height > ( s_backbuffer_height - Y ) ) Height = s_backbuffer_height - Y ;
2010-09-30 15:24:34 +00:00
2010-03-14 18:57:50 +00:00
vp . X = X ;
vp . Y = Y ;
vp . Width = Width ;
vp . Height = Height ;
vp . MinZ = 0.0f ;
vp . MaxZ = 1.0f ;
D3D : : dev - > SetViewport ( & vp ) ;
D3D : : ChangeSamplerState ( 0 , D3DSAMP_MINFILTER , D3DTEXF_LINEAR ) ;
D3D : : ChangeSamplerState ( 0 , D3DSAMP_MAGFILTER , D3DTEXF_LINEAR ) ;
2010-11-14 23:31:53 +00:00
const XFBSourceBase * xfbSource = NULL ;
2010-09-30 15:24:34 +00:00
2010-07-02 17:09:53 +00:00
if ( g_ActiveConfig . bUseXFB )
2010-03-14 18:57:50 +00:00
{
2010-07-02 17:09:53 +00:00
// draw each xfb source
2010-09-30 15:24:34 +00:00
// Render to the real buffer now.
2010-07-02 17:09:53 +00:00
for ( u32 i = 0 ; i < xfbCount ; + + i )
2010-03-14 18:57:50 +00:00
{
2010-09-28 02:15:02 +00:00
xfbSource = xfbSourceList [ i ] ;
2010-09-30 15:24:34 +00:00
2010-07-02 17:09:53 +00:00
MathUtil : : Rectangle < float > sourceRc ;
2010-05-24 14:20:19 +00:00
2010-07-02 17:09:53 +00:00
sourceRc . left = 0 ;
sourceRc . top = 0 ;
2010-12-10 15:54:14 +00:00
sourceRc . right = ( float ) xfbSource - > texWidth ;
sourceRc . bottom = ( float ) xfbSource - > texHeight ;
2010-07-02 17:09:53 +00:00
MathUtil : : Rectangle < float > drawRc ;
2010-03-14 18:57:50 +00:00
2012-09-28 21:21:09 +00:00
if ( g_ActiveConfig . bUseRealXFB )
{
drawRc . top = - 1 ;
drawRc . bottom = 1 ;
drawRc . left = - 1 ;
drawRc . right = 1 ;
}
else
2010-03-14 18:57:50 +00:00
{
2010-07-02 17:09:53 +00:00
// use virtual xfb with offset
int xfbHeight = xfbSource - > srcHeight ;
int xfbWidth = xfbSource - > srcWidth ;
int hOffset = ( ( s32 ) xfbSource - > srcAddr - ( s32 ) xfbAddr ) / ( ( s32 ) fbWidth * 2 ) ;
2010-09-28 02:15:02 +00:00
drawRc . bottom = 1.0f - ( 2.0f * ( hOffset ) / ( float ) fbHeight ) ;
drawRc . top = 1.0f - ( 2.0f * ( hOffset + xfbHeight ) / ( float ) fbHeight ) ;
2010-07-02 17:09:53 +00:00
drawRc . left = - ( xfbWidth / ( float ) fbWidth ) ;
drawRc . right = ( xfbWidth / ( float ) fbWidth ) ;
2010-09-30 15:24:34 +00:00
// The following code disables auto stretch. Kept for reference.
// scale draw area for a 1 to 1 pixel mapping with the draw target
2012-09-28 22:04:55 +00:00
//float vScale = (float)fbHeight / (float)GetTargetRectangle().GetHeight();
//float hScale = (float)fbWidth / (float)GetTargetRectangle().GetWidth();
2010-09-30 15:24:34 +00:00
//drawRc.top *= vScale;
//drawRc.bottom *= vScale;
//drawRc.left *= hScale;
//drawRc.right *= hScale;
2010-07-02 17:09:53 +00:00
}
2010-03-14 18:57:50 +00:00
2010-11-14 23:31:53 +00:00
xfbSource - > Draw ( sourceRc , drawRc , Width , Height ) ;
2010-07-02 17:09:53 +00:00
}
}
else
{
2010-09-30 15:24:34 +00:00
TargetRectangle targetRc = ConvertEFBRectangle ( rc ) ;
2010-11-14 23:31:53 +00:00
LPDIRECT3DTEXTURE9 read_texture = FramebufferManager : : GetEFBColorTexture ( ) ;
2011-05-12 02:14:45 +00:00
D3D : : drawShadedTexQuad ( read_texture , targetRc . AsRECT ( ) ,
Renderer : : GetTargetWidth ( ) , Renderer : : GetTargetHeight ( ) ,
Width , Height ,
PixelShaderCache : : GetColorCopyProgram ( g_ActiveConfig . iMultisampleMode ) ,
VertexShaderCache : : GetSimpleVertexShader ( g_ActiveConfig . iMultisampleMode ) , Gamma ) ;
2011-01-07 19:23:57 +00:00
2010-03-14 18:57:50 +00:00
}
D3D : : RefreshSamplerState ( 0 , D3DSAMP_MINFILTER ) ;
2010-07-06 13:14:51 +00:00
D3D : : RefreshSamplerState ( 0 , D3DSAMP_MAGFILTER ) ;
2010-09-30 15:24:34 +00:00
2010-09-23 02:17:48 +00:00
if ( g_ActiveConfig . bAnaglyphStereo )
{
DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE ;
D3D : : SetRenderState ( D3DRS_COLORWRITEENABLE , color_mask ) ;
}
2010-09-30 15:24:34 +00:00
2010-03-14 18:57:50 +00:00
vp . X = 0 ;
vp . Y = 0 ;
vp . Width = s_backbuffer_width ;
vp . Height = s_backbuffer_height ;
vp . MinZ = 0.0f ;
vp . MaxZ = 1.0f ;
D3D : : dev - > SetViewport ( & vp ) ;
2010-09-30 15:24:34 +00:00
// Save screenshot
2010-09-28 02:15:02 +00:00
if ( s_bScreenshot )
2010-03-14 18:57:50 +00:00
{
2011-03-05 06:11:26 +00:00
std : : lock_guard < std : : mutex > lk ( s_criticalScreenshot ) ;
2012-09-28 22:04:55 +00:00
SaveScreenshot ( s_sScreenshotName , GetTargetRectangle ( ) ) ;
2010-03-14 18:57:50 +00:00
s_bScreenshot = false ;
}
2011-09-08 13:39:03 +00:00
// Dump frames
static int w = 0 , h = 0 ;
2010-07-06 13:14:51 +00:00
if ( g_ActiveConfig . bDumpFrames )
2010-03-14 18:57:50 +00:00
{
2011-09-08 13:39:03 +00:00
static int s_recordWidth ;
static int s_recordHeight ;
2010-07-09 20:56:16 +00:00
HRESULT hr = D3D : : dev - > GetRenderTargetData ( D3D : : GetBackBufferSurface ( ) , ScreenShootMEMSurface ) ;
2011-09-08 13:39:03 +00:00
if ( ! bLastFrameDumped )
2010-03-14 18:57:50 +00:00
{
2012-09-28 22:04:55 +00:00
s_recordWidth = GetTargetRectangle ( ) . GetWidth ( ) ;
s_recordHeight = GetTargetRectangle ( ) . GetHeight ( ) ;
2011-09-08 15:09:24 +00:00
bAVIDumping = AVIDump : : Start ( EmuWindow : : GetParentWnd ( ) , s_recordWidth , s_recordHeight ) ;
if ( ! bAVIDumping )
2010-03-14 18:57:50 +00:00
{
PanicAlert ( " Error dumping frames to AVI. " ) ;
2010-07-06 13:14:51 +00:00
}
else
2010-03-14 18:57:50 +00:00
{
char msg [ 255 ] ;
2011-02-28 20:40:15 +00:00
sprintf_s ( msg , 255 , " Dumping Frames to \" %sframedump0.avi \" (%dx%d RGB24) " ,
File : : GetUserPath ( D_DUMPFRAMES_IDX ) . c_str ( ) , s_recordWidth , s_recordHeight ) ;
2010-03-14 18:57:50 +00:00
OSD : : AddMessage ( msg , 2000 ) ;
}
}
2011-09-08 15:09:24 +00:00
if ( bAVIDumping )
2010-03-14 18:57:50 +00:00
{
D3DLOCKED_RECT rect ;
2012-09-28 22:04:55 +00:00
if ( SUCCEEDED ( ScreenShootMEMSurface - > LockRect ( & rect , GetTargetRectangle ( ) . AsRECT ( ) , D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY ) ) )
2010-03-14 18:57:50 +00:00
{
2013-02-27 01:47:48 +00:00
if ( frame_data . empty ( ) | | w ! = s_recordWidth | | h ! = s_recordHeight )
2011-02-11 18:59:42 +00:00
{
2013-02-27 01:47:48 +00:00
frame_data . resize ( 3 * s_recordWidth * s_recordHeight ) ;
2011-02-11 18:59:42 +00:00
w = s_recordWidth ;
h = s_recordHeight ;
}
2013-02-27 01:47:48 +00:00
formatBufferDump ( ( const u8 * ) rect . pBits , & frame_data [ 0 ] , s_recordWidth , s_recordHeight , rect . Pitch ) ;
AVIDump : : AddFrame ( & frame_data [ 0 ] , fbWidth , fbHeight ) ;
2010-03-14 18:57:50 +00:00
ScreenShootMEMSurface - > UnlockRect ( ) ;
}
}
2011-09-08 13:39:03 +00:00
bLastFrameDumped = true ;
2010-07-06 13:14:51 +00:00
}
else
2010-03-14 18:57:50 +00:00
{
2011-09-08 15:09:24 +00:00
if ( bLastFrameDumped & & bAVIDumping )
2010-03-14 18:57:50 +00:00
{
2013-02-27 01:47:48 +00:00
std : : vector < u8 > ( ) . swap ( frame_data ) ;
w = h = 0 ;
2010-03-14 18:57:50 +00:00
AVIDump : : Stop ( ) ;
2011-09-08 15:09:24 +00:00
bAVIDumping = false ;
2010-09-28 02:15:02 +00:00
OSD : : AddMessage ( " Stop dumping frames to AVI " , 2000 ) ;
2010-03-14 18:57:50 +00:00
}
2011-09-08 13:39:03 +00:00
bLastFrameDumped = false ;
2010-03-14 18:57:50 +00:00
}
// Finish up the current frame, print some stats
if ( g_ActiveConfig . bShowFPS )
{
char fps [ 20 ] ;
StringCchPrintfA ( fps , 20 , " FPS: %d \n " , s_fps ) ;
2011-02-17 09:12:36 +00:00
D3D : : font . DrawTextScaled ( 0 , 0 , 20 , 20 , 0.0f , 0xFF00FFFF , fps ) ;
}
2012-11-14 21:21:54 +00:00
if ( SConfig : : GetInstance ( ) . m_ShowLag )
2012-11-11 22:57:06 +00:00
{
char lag [ 10 ] ;
2013-06-18 14:48:16 +00:00
StringCchPrintfA ( lag , 10 , " Lag: %llu \n " , Movie : : g_currentLagCount ) ;
2012-11-11 22:57:06 +00:00
D3D : : font . DrawTextScaled ( 0 , 18 , 20 , 20 , 0.0f , 0xFF00FFFF , lag ) ;
}
2011-02-17 09:12:36 +00:00
if ( g_ActiveConfig . bShowInputDisplay )
{
char inputDisplay [ 1000 ] ;
2011-06-24 06:50:50 +00:00
StringCchPrintfA ( inputDisplay , 1000 , Movie : : GetInputDisplay ( ) . c_str ( ) ) ;
2012-11-11 22:57:06 +00:00
D3D : : font . DrawTextScaled ( 0 , 36 , 20 , 20 , 0.0f , 0xFF00FFFF , inputDisplay ) ;
2010-03-14 18:57:50 +00:00
}
2012-11-11 22:57:06 +00:00
2010-03-14 18:57:50 +00:00
Renderer : : DrawDebugText ( ) ;
if ( g_ActiveConfig . bOverlayStats )
{
Statistics : : ToString ( st ) ;
2012-11-11 22:57:06 +00:00
D3D : : font . DrawTextScaled ( 0 , 36 , 20 , 20 , 0.0f , 0xFF00FFFF , st ) ;
2010-03-14 18:57:50 +00:00
}
else if ( g_ActiveConfig . bOverlayProjStats )
{
Statistics : : ToStringProj ( st ) ;
2012-11-12 16:39:33 +00:00
D3D : : font . DrawTextScaled ( 0 , 36 , 20 , 20 , 0.0f , 0xFF00FFFF , st ) ;
2010-03-14 18:57:50 +00:00
}
OSD : : DrawMessages ( ) ;
D3D : : EndFrame ( ) ;
2012-10-04 03:41:02 +00:00
+ + frameCount ;
2010-11-29 16:16:48 +00:00
2010-12-05 14:15:36 +00:00
GFX_DEBUGGER_PAUSE_AT ( NEXT_FRAME , true ) ;
2010-11-29 16:16:48 +00:00
2010-08-29 23:08:56 +00:00
DLCache : : ProgressiveCleanup ( ) ;
2009-09-20 03:29:43 +00:00
TextureCache : : Cleanup ( ) ;
2013-04-01 17:23:48 +00:00
// Flip/present backbuffer to frontbuffer here
D3D : : Present ( ) ;
2011-12-26 21:04:59 +00:00
// Enable configuration changes
2010-07-06 13:14:51 +00:00
UpdateActiveConfig ( ) ;
2012-05-28 09:31:37 +00:00
TextureCache : : OnConfigChanged ( g_ActiveConfig ) ;
2011-01-07 04:57:59 +00:00
2011-01-25 03:30:12 +00:00
SetWindowSize ( fbWidth , fbHeight ) ;
2011-01-07 04:57:59 +00:00
const bool windowResized = CheckForResize ( ) ;
2010-09-28 02:15:02 +00:00
2010-03-14 18:57:50 +00:00
bool xfbchanged = false ;
2010-09-28 02:15:02 +00:00
2012-09-28 21:48:18 +00:00
if ( FramebufferManagerBase : : LastXfbWidth ( ) ! = fbWidth | | FramebufferManagerBase : : LastXfbHeight ( ) ! = fbHeight )
2010-03-14 18:57:50 +00:00
{
xfbchanged = true ;
2012-09-28 21:48:18 +00:00
unsigned int w = ( fbWidth < 1 | | fbWidth > MAX_XFB_WIDTH ) ? MAX_XFB_WIDTH : fbWidth ;
unsigned int h = ( fbHeight < 1 | | fbHeight > MAX_XFB_HEIGHT ) ? MAX_XFB_HEIGHT : fbHeight ;
FramebufferManagerBase : : SetLastXfbWidth ( w ) ;
FramebufferManagerBase : : SetLastXfbHeight ( h ) ;
2010-03-14 18:57:50 +00:00
}
2009-09-20 03:29:43 +00:00
2010-02-05 21:55:02 +00:00
u32 newAA = g_ActiveConfig . iMultisampleMode ;
2010-09-30 15:24:34 +00:00
2011-01-07 04:57:59 +00:00
if ( xfbchanged | | windowResized | | s_LastEFBScale ! = g_ActiveConfig . iEFBScale | | s_LastAA ! = newAA )
2010-07-06 13:14:51 +00:00
{
2010-02-03 22:19:00 +00:00
s_LastAA = newAA ;
2010-03-14 18:57:50 +00:00
2012-09-28 22:04:55 +00:00
UpdateDrawRectangle ( s_backbuffer_width , s_backbuffer_height ) ;
2010-03-14 18:57:50 +00:00
2011-01-07 19:23:57 +00:00
int SupersampleCoeficient = ( s_LastAA % 3 ) + 1 ;
2010-09-30 15:24:34 +00:00
2010-11-18 02:21:26 +00:00
s_LastEFBScale = g_ActiveConfig . iEFBScale ;
2012-09-28 22:19:28 +00:00
CalculateTargetSize ( s_backbuffer_width , s_backbuffer_height , SupersampleCoeficient ) ;
2010-09-30 15:24:34 +00:00
2010-02-03 22:19:00 +00:00
D3D : : dev - > SetRenderTarget ( 0 , D3D : : GetBackBufferSurface ( ) ) ;
D3D : : dev - > SetDepthStencilSurface ( D3D : : GetBackBufferDepthSurface ( ) ) ;
2011-01-07 04:57:59 +00:00
if ( windowResized )
2010-03-22 00:21:39 +00:00
{
2011-01-31 13:17:57 +00:00
// device objects lost, so recreate all of them
2010-03-22 00:21:39 +00:00
SetupDeviceObjects ( ) ;
}
else
{
2011-01-31 13:17:57 +00:00
// just resize the frame buffer
2010-11-14 23:31:53 +00:00
delete g_framebuffer_manager ;
g_framebuffer_manager = new FramebufferManager ;
2010-03-22 00:21:39 +00:00
}
2010-11-14 23:31:53 +00:00
D3D : : dev - > SetRenderTarget ( 0 , FramebufferManager : : GetEFBColorRTSurface ( ) ) ;
D3D : : dev - > SetDepthStencilSurface ( FramebufferManager : : GetEFBDepthRTSurface ( ) ) ;
2011-01-06 16:05:11 +00:00
D3D : : dev - > Clear ( 0 , NULL , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB ( 0 , 0 , 0 ) , 1.0f , 0 ) ;
2010-02-03 22:19:00 +00:00
}
2010-08-01 14:43:07 +00:00
if ( XFBWrited )
2012-10-04 03:41:02 +00:00
s_fps = UpdateFPSCounter ( ) ;
2009-09-20 03:29:43 +00:00
// Begin new frame
// Set default viewport and scissor, for the clear to work correctly
2010-09-28 02:15:02 +00:00
// New frame
2009-09-20 03:29:43 +00:00
stats . ResetFrame ( ) ;
2013-04-01 17:23:48 +00:00
// Handle vsync changes during execution
if ( s_vsync ! = g_ActiveConfig . IsVSync ( ) )
{
s_vsync = g_ActiveConfig . IsVSync ( ) ;
TeardownDeviceObjects ( ) ;
D3D : : Reset ( ) ;
// device objects lost, so recreate all of them
SetupDeviceObjects ( ) ;
}
2010-03-14 18:57:50 +00:00
D3D : : BeginFrame ( ) ;
2010-09-30 15:24:34 +00:00
RestoreAPIState ( ) ;
2010-11-14 23:31:53 +00:00
D3D : : dev - > SetRenderTarget ( 0 , FramebufferManager : : GetEFBColorRTSurface ( ) ) ;
D3D : : dev - > SetDepthStencilSurface ( FramebufferManager : : GetEFBDepthRTSurface ( ) ) ;
2010-03-14 18:57:50 +00:00
VertexShaderManager : : SetViewportChanged ( ) ;
2011-01-31 13:17:57 +00:00
2011-01-31 01:28:32 +00:00
Core : : Callback_VideoCopiedToXFB ( XFBWrited | | ( g_ActiveConfig . bUseXFB & & g_ActiveConfig . bUseRealXFB ) ) ;
2010-03-14 18:57:50 +00:00
XFBWrited = false ;
2009-09-20 03:29:43 +00:00
}
2009-11-08 20:35:11 +00:00
2012-08-10 16:57:37 +00:00
void Renderer : : ApplyState ( bool bUseDstAlpha )
2011-01-24 10:42:43 +00:00
{
2012-08-10 16:57:37 +00:00
if ( bUseDstAlpha )
2011-01-24 10:42:43 +00:00
{
2013-04-01 17:23:48 +00:00
// If we get here we are sure that we are using dst alpha pass. (bpmem.dstalpha.enable)
// Alpha write is enabled. (because bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)
// We must disable blend because we want to write alpha value directly to the alpha channel without modifications.
2011-01-24 10:42:43 +00:00
D3D : : ChangeRenderState ( D3DRS_COLORWRITEENABLE , D3DCOLORWRITEENABLE_ALPHA ) ;
D3D : : ChangeRenderState ( D3DRS_ALPHABLENDENABLE , false ) ;
2012-10-20 13:22:15 +00:00
if ( bpmem . zmode . testenable & & bpmem . zmode . updateenable )
{
2013-04-01 17:23:48 +00:00
// This is needed to draw to the correct pixels in multi-pass algorithms
2013-04-07 21:11:29 +00:00
// to avoid z-fighting and grants that you write to the same pixels
2013-04-01 17:23:48 +00:00
// affected by the last pass
2012-10-20 13:22:15 +00:00
D3D : : ChangeRenderState ( D3DRS_ZWRITEENABLE , false ) ;
D3D : : ChangeRenderState ( D3DRS_ZFUNC , D3DCMP_EQUAL ) ;
}
2011-01-24 10:42:43 +00:00
}
}
2012-03-29 23:56:24 +00:00
void Renderer : : RestoreState ( )
2011-01-24 10:42:43 +00:00
{
2012-08-10 16:57:37 +00:00
D3D : : RefreshRenderState ( D3DRS_COLORWRITEENABLE ) ;
D3D : : RefreshRenderState ( D3DRS_ALPHABLENDENABLE ) ;
2012-10-20 13:22:15 +00:00
if ( bpmem . zmode . testenable & & bpmem . zmode . updateenable )
{
D3D : : RefreshRenderState ( D3DRS_ZWRITEENABLE ) ;
D3D : : RefreshRenderState ( D3DRS_ZFUNC ) ;
}
2011-01-24 10:42:43 +00:00
// TODO: Enable this code. Caused glitches for me however (neobrain)
// for (unsigned int i = 0; i < 8; ++i)
// D3D::dev->SetTexture(i, NULL);
}
2010-09-28 02:15:02 +00:00
// ALWAYS call RestoreAPIState for each ResetAPIState call you're doing
2009-11-08 20:35:11 +00:00
void Renderer : : ResetAPIState ( )
{
2011-02-06 18:43:56 +00:00
D3D : : SetRenderState ( D3DRS_FILLMODE , D3DFILL_SOLID ) ;
2010-01-15 22:07:53 +00:00
D3D : : SetRenderState ( D3DRS_SCISSORTESTENABLE , FALSE ) ;
2010-06-08 02:56:00 +00:00
D3D : : SetRenderState ( D3DRS_CULLMODE , D3DCULL_NONE ) ;
2010-02-25 06:12:35 +00:00
D3D : : SetRenderState ( D3DRS_ALPHABLENDENABLE , FALSE ) ;
D3D : : SetRenderState ( D3DRS_ZENABLE , FALSE ) ;
2010-06-08 02:56:00 +00:00
D3D : : SetRenderState ( D3DRS_ZWRITEENABLE , FALSE ) ;
2010-07-06 13:14:51 +00:00
DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE ;
2010-01-15 22:07:53 +00:00
D3D : : SetRenderState ( D3DRS_COLORWRITEENABLE , color_mask ) ;
2009-11-08 20:35:11 +00:00
}
void Renderer : : RestoreAPIState ( )
{
// Gets us back into a more game-like state.
2011-02-06 18:43:56 +00:00
D3D : : SetRenderState ( D3DRS_FILLMODE , g_ActiveConfig . bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID ) ;
2010-01-15 22:07:53 +00:00
D3D : : SetRenderState ( D3DRS_SCISSORTESTENABLE , TRUE ) ;
2011-05-12 02:14:45 +00:00
VertexShaderManager : : SetViewportChanged ( ) ;
2011-09-05 20:04:28 +00:00
BPFunctions : : SetScissor ( ) ;
2011-03-04 23:14:21 +00:00
if ( bpmem . zmode . testenable ) {
2010-07-06 13:14:51 +00:00
D3D : : SetRenderState ( D3DRS_ZENABLE , TRUE ) ;
2011-03-04 23:14:21 +00:00
if ( bpmem . zmode . updateenable )
D3D : : SetRenderState ( D3DRS_ZWRITEENABLE , TRUE ) ;
}
2010-02-25 06:12:35 +00:00
SetColorMask ( ) ;
2010-01-15 22:07:53 +00:00
SetLogicOpMode ( ) ;
2011-02-25 20:24:48 +00:00
SetGenerationMode ( ) ;
2009-11-08 20:35:11 +00:00
}
2009-11-23 14:08:08 +00:00
void Renderer : : SetGenerationMode ( )
{
2013-01-13 22:35:07 +00:00
const D3DCULL d3dCullModes [ 4 ] =
{
D3DCULL_NONE ,
D3DCULL_CCW ,
D3DCULL_CW ,
D3DCULL_CCW
} ;
2010-02-25 06:12:35 +00:00
D3D : : SetRenderState ( D3DRS_CULLMODE , d3dCullModes [ bpmem . genMode . cullmode ] ) ;
2009-11-23 14:08:08 +00:00
}
void Renderer : : SetDepthMode ( )
{
2013-01-13 22:35:07 +00:00
const D3DCMPFUNC d3dCmpFuncs [ 8 ] =
{
D3DCMP_NEVER ,
D3DCMP_LESS ,
D3DCMP_EQUAL ,
D3DCMP_LESSEQUAL ,
D3DCMP_GREATER ,
D3DCMP_NOTEQUAL ,
D3DCMP_GREATEREQUAL ,
D3DCMP_ALWAYS
} ;
2009-11-23 14:08:08 +00:00
if ( bpmem . zmode . testenable )
{
D3D : : SetRenderState ( D3DRS_ZENABLE , TRUE ) ;
D3D : : SetRenderState ( D3DRS_ZWRITEENABLE , bpmem . zmode . updateenable ) ;
2010-02-25 06:12:35 +00:00
D3D : : SetRenderState ( D3DRS_ZFUNC , d3dCmpFuncs [ bpmem . zmode . func ] ) ;
2009-11-23 14:08:08 +00:00
}
else
{
2010-09-28 02:15:02 +00:00
// if the test is disabled write is disabled too
2009-11-23 14:08:08 +00:00
D3D : : SetRenderState ( D3DRS_ZENABLE , FALSE ) ;
2011-03-04 23:14:21 +00:00
D3D : : SetRenderState ( D3DRS_ZWRITEENABLE , FALSE ) ;
2010-02-25 06:12:35 +00:00
}
2009-11-23 14:08:08 +00:00
}
2009-11-27 19:42:27 +00:00
void Renderer : : SetLogicOpMode ( )
{
2013-01-13 22:35:07 +00:00
// D3D9 doesn't support logic blending, so this is a huge hack
// 0 0x00
// 1 Source & destination
// 2 Source & ~destination
// 3 Source
// 4 ~Source & destination
// 5 Destination
// 6 Source ^ destination = Source & ~destination | ~Source & destination
// 7 Source | destination
// 8 ~(Source | destination)
// 9 ~(Source ^ destination) = ~Source & ~destination | Source & destination
// 10 ~Destination
// 11 Source | ~destination
// 12 ~Source
// 13 ~Source | destination
// 14 ~(Source & destination)
// 15 0xff
const D3DBLENDOP d3dLogicOpop [ 16 ] =
{
D3DBLENDOP_ADD ,
D3DBLENDOP_ADD ,
D3DBLENDOP_SUBTRACT ,
D3DBLENDOP_ADD ,
D3DBLENDOP_REVSUBTRACT ,
D3DBLENDOP_ADD ,
D3DBLENDOP_MAX ,
D3DBLENDOP_ADD ,
D3DBLENDOP_MAX ,
D3DBLENDOP_MAX ,
D3DBLENDOP_ADD ,
D3DBLENDOP_ADD ,
D3DBLENDOP_ADD ,
D3DBLENDOP_ADD ,
D3DBLENDOP_ADD ,
D3DBLENDOP_ADD
} ;
const D3DBLEND d3dLogicOpSrcFactors [ 16 ] =
{
D3DBLEND_ZERO ,
D3DBLEND_DESTCOLOR ,
D3DBLEND_ONE ,
D3DBLEND_ONE ,
D3DBLEND_DESTCOLOR ,
D3DBLEND_ZERO ,
D3DBLEND_INVDESTCOLOR ,
D3DBLEND_INVDESTCOLOR ,
D3DBLEND_INVSRCCOLOR ,
D3DBLEND_INVSRCCOLOR ,
D3DBLEND_INVDESTCOLOR ,
D3DBLEND_ONE ,
D3DBLEND_INVSRCCOLOR ,
D3DBLEND_INVSRCCOLOR ,
D3DBLEND_INVDESTCOLOR ,
D3DBLEND_ONE
} ;
const D3DBLEND d3dLogicOpDestFactors [ 16 ] =
{
D3DBLEND_ZERO ,
D3DBLEND_ZERO ,
D3DBLEND_INVSRCCOLOR ,
D3DBLEND_ZERO ,
D3DBLEND_ONE ,
D3DBLEND_ONE ,
D3DBLEND_INVSRCCOLOR ,
D3DBLEND_ONE ,
D3DBLEND_INVDESTCOLOR ,
D3DBLEND_SRCCOLOR ,
D3DBLEND_INVDESTCOLOR ,
D3DBLEND_INVDESTCOLOR ,
D3DBLEND_INVSRCCOLOR ,
D3DBLEND_ONE ,
D3DBLEND_INVSRCCOLOR ,
D3DBLEND_ONE
} ;
if ( bpmem . blendmode . logicopenable )
2009-12-07 18:48:31 +00:00
{
2010-06-24 15:58:06 +00:00
D3D : : SetRenderState ( D3DRS_ALPHABLENDENABLE , true ) ;
2010-06-05 01:38:22 +00:00
D3D : : SetRenderState ( D3DRS_BLENDOP , d3dLogicOpop [ bpmem . blendmode . logicmode ] ) ;
2009-12-07 18:48:31 +00:00
D3D : : SetRenderState ( D3DRS_SRCBLEND , d3dLogicOpSrcFactors [ bpmem . blendmode . logicmode ] ) ;
D3D : : SetRenderState ( D3DRS_DESTBLEND , d3dLogicOpDestFactors [ bpmem . blendmode . logicmode ] ) ;
}
else
{
SetBlendMode ( true ) ;
}
2009-11-27 19:42:27 +00:00
}
void Renderer : : SetDitherMode ( )
{
2010-07-06 13:14:51 +00:00
D3D : : SetRenderState ( D3DRS_DITHERENABLE , bpmem . blendmode . dither ) ;
2009-11-27 19:42:27 +00:00
}
void Renderer : : SetLineWidth ( )
{
// We can't change line width in D3D unless we use ID3DXLine
2011-04-11 01:49:32 +00:00
float fratio = xfregs . viewport . wd ! = 0 ? Renderer : : EFBToScaledXf ( 1.f ) : 1.0f ;
2010-12-10 16:13:43 +00:00
float psize = bpmem . lineptwidth . linesize * fratio / 6.0f ;
2013-04-07 21:11:29 +00:00
//little hack to compensate scaling problems in dx9 must be taken out when scaling is fixed.
2012-11-12 22:37:08 +00:00
psize * = 2.0f ;
if ( psize > m_fMaxPointSize )
{
psize = m_fMaxPointSize ;
}
2010-12-10 16:13:43 +00:00
D3D : : SetRenderState ( D3DRS_POINTSIZE , * ( ( DWORD * ) & psize ) ) ;
2012-11-12 22:37:08 +00:00
D3D : : SetRenderState ( D3DRS_POINTSIZE_MIN , * ( ( DWORD * ) & psize ) ) ;
D3D : : SetRenderState ( D3DRS_POINTSIZE_MAX , * ( ( DWORD * ) & psize ) ) ;
2009-11-27 19:42:27 +00:00
}
2010-01-12 23:40:30 +00:00
void Renderer : : SetSamplerState ( int stage , int texindex )
2009-11-27 19:42:27 +00:00
{
2013-01-13 22:35:07 +00:00
const D3DTEXTUREFILTERTYPE d3dMipFilters [ 4 ] =
{
D3DTEXF_NONE ,
D3DTEXF_POINT ,
D3DTEXF_LINEAR ,
D3DTEXF_NONE , //reserved
} ;
const D3DTEXTUREADDRESS d3dClamps [ 4 ] =
{
D3DTADDRESS_CLAMP ,
D3DTADDRESS_WRAP ,
D3DTADDRESS_MIRROR ,
D3DTADDRESS_WRAP //reserved
} ;
2010-07-06 13:14:51 +00:00
const FourTexUnits & tex = bpmem . tex [ texindex ] ;
2009-11-27 19:42:27 +00:00
const TexMode0 & tm0 = tex . texMode0 [ stage ] ;
2010-04-14 13:57:16 +00:00
const TexMode1 & tm1 = tex . texMode1 [ stage ] ;
2009-11-27 19:42:27 +00:00
D3DTEXTUREFILTERTYPE min , mag , mip ;
if ( g_ActiveConfig . bForceFiltering )
{
min = mag = mip = D3DTEXF_LINEAR ;
}
else
{
min = ( tm0 . min_filter & 4 ) ? D3DTEXF_LINEAR : D3DTEXF_POINT ;
mag = tm0 . mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT ;
2013-01-13 22:35:07 +00:00
mip = d3dMipFilters [ tm0 . min_filter & 3 ] ;
2009-11-27 19:42:27 +00:00
}
if ( texindex )
2010-07-06 13:14:51 +00:00
stage + = 4 ;
2013-01-13 22:35:07 +00:00
2011-02-05 22:32:20 +00:00
if ( mag = = D3DTEXF_LINEAR & & min = = D3DTEXF_LINEAR & & g_ActiveConfig . iMaxAnisotropy )
2009-11-27 19:42:27 +00:00
{
min = D3DTEXF_ANISOTROPIC ;
}
D3D : : SetSamplerState ( stage , D3DSAMP_MINFILTER , min ) ;
D3D : : SetSamplerState ( stage , D3DSAMP_MAGFILTER , mag ) ;
D3D : : SetSamplerState ( stage , D3DSAMP_MIPFILTER , mip ) ;
D3D : : SetSamplerState ( stage , D3DSAMP_ADDRESSU , d3dClamps [ tm0 . wrap_s ] ) ;
D3D : : SetSamplerState ( stage , D3DSAMP_ADDRESSV , d3dClamps [ tm0 . wrap_t ] ) ;
2012-08-10 11:24:40 +00:00
2012-08-10 11:27:35 +00:00
float lodbias = ( s32 ) tm0 . lod_bias / 32.0f ;
2010-07-06 13:14:51 +00:00
D3D : : SetSamplerState ( stage , D3DSAMP_MIPMAPLODBIAS , * ( DWORD * ) & lodbias ) ;
D3D : : SetSamplerState ( stage , D3DSAMP_MAXMIPLEVEL , tm1 . min_lod > > 4 ) ;
2009-11-27 19:42:27 +00:00
}
void Renderer : : SetInterlacingMode ( )
{
// TODO
}
2010-01-27 22:07:59 +00:00
2011-01-29 20:16:51 +00:00
} // namespace DX9