Second Experimental commit:

corrected peek color and peek z to  correctly emulate real hardware formats.
implements native gamma correction.(i don't own any game that uses this functionality so i will appreciate feedback)
i need a lot of feedback in this changes please
enjoy

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6664 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Rodolfo Osvaldo Bogado 2010-12-27 03:18:01 +00:00
parent f3336a84a1
commit c2283ad6c0
25 changed files with 201 additions and 101 deletions

View File

@ -99,15 +99,15 @@ const XFBSourceBase* const* FramebufferManagerBase::GetVirtualXFBSource(u32 xfbA
return &m_overlappingXFBArray[0]; return &m_overlappingXFBArray[0];
} }
void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
{ {
if (g_ActiveConfig.bUseRealXFB) if (g_ActiveConfig.bUseRealXFB)
g_framebuffer_manager->CopyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc); g_framebuffer_manager->CopyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc,Gamma);
else else
CopyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc); CopyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc,Gamma);
} }
void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
{ {
VirtualXFBListType::iterator vxfb = FindVirtualXFB(xfbAddr, fbWidth, fbHeight); VirtualXFBListType::iterator vxfb = FindVirtualXFB(xfbAddr, fbWidth, fbHeight);
@ -162,7 +162,7 @@ void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHe
g_renderer->ResetAPIState(); // reset any game specific settings g_renderer->ResetAPIState(); // reset any game specific settings
// Copy EFB data to XFB and restore render target again // Copy EFB data to XFB and restore render target again
vxfb->xfbSource->CopyEFB(); vxfb->xfbSource->CopyEFB(Gamma);
g_renderer->RestoreAPIState(); g_renderer->RestoreAPIState();
} }

View File

@ -21,7 +21,7 @@ struct XFBSourceBase
virtual void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) = 0; virtual void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) = 0;
virtual void CopyEFB() = 0; virtual void CopyEFB(float Gamma) = 0;
u32 srcAddr; u32 srcAddr;
u32 srcWidth; u32 srcWidth;
@ -47,7 +47,7 @@ public:
FramebufferManagerBase(); FramebufferManagerBase();
virtual ~FramebufferManagerBase(); virtual ~FramebufferManagerBase();
static void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); static void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma);
static const XFBSourceBase* const* GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); static const XFBSourceBase* const* GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
protected: protected:
@ -75,8 +75,8 @@ private:
static void ReplaceVirtualXFB(); static void ReplaceVirtualXFB();
// TODO: merge these virtual funcs, they are nearly all the same // TODO: merge these virtual funcs, they are nearly all the same
virtual void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) = 0; virtual void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma = 1.0f) = 0;
static void CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); static void CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma = 1.0f);
static const XFBSourceBase* const* GetRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); static const XFBSourceBase* const* GetRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
static const XFBSourceBase* const* GetVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); static const XFBSourceBase* const* GetVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);

View File

@ -87,7 +87,7 @@ Renderer::~Renderer()
} }
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
{ {
if (!fbWidth || !fbHeight) if (!fbWidth || !fbHeight)
return; return;
@ -102,11 +102,11 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
// just use progressive. // just use progressive.
if (g_ActiveConfig.bUseXFB) if (g_ActiveConfig.bUseXFB)
{ {
FramebufferManagerBase::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); FramebufferManagerBase::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc,Gamma);
} }
else else
{ {
g_renderer->Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight,sourceRc); g_renderer->Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight,sourceRc,Gamma);
Common::AtomicStoreRelease(s_swapRequested, FALSE); Common::AtomicStoreRelease(s_swapRequested, FALSE);
} }
} }

View File

@ -110,7 +110,7 @@ public:
virtual void RenderText(const char* pstr, int left, int top, u32 color) = 0; virtual void RenderText(const char* pstr, int left, int top, u32 color) = 0;
virtual void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) = 0; virtual void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) = 0;
static void RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); static void RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma = 1.0f);
virtual u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) = 0; virtual u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) = 0;
@ -119,7 +119,7 @@ public:
virtual void RestoreAPIState() = 0; virtual void RestoreAPIState() = 0;
// Finish up the current frame, print some stats // Finish up the current frame, print some stats
virtual void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc) = 0; virtual void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma = 1.0f) = 0;
virtual void UpdateViewport() = 0; virtual void UpdateViewport() = 0;

View File

@ -430,20 +430,20 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
ID3D11SamplerState* linear_copy_sampler = NULL; ID3D11SamplerState* linear_copy_sampler = NULL;
ID3D11SamplerState* point_copy_sampler = NULL; ID3D11SamplerState* point_copy_sampler = NULL;
typedef struct { float x,y,z,u,v; } STQVertex; typedef struct { float x,y,z,u,v,w; } STQVertex;
typedef struct { float x,y,z,u,v; } STSQVertex; typedef struct { float x,y,z,u,v,w; } STSQVertex;
typedef struct { float x,y,z; u32 col; } ClearVertex; typedef struct { float x,y,z; u32 col; } ClearVertex;
typedef struct { float x,y,z; u32 col; } ColVertex; typedef struct { float x,y,z; u32 col; } ColVertex;
struct struct
{ {
float u1, v1, u2, v2; float u1, v1, u2, v2, G;
} tex_quad_data; } tex_quad_data;
struct struct
{ {
MathUtil::Rectangle<float> rdest; MathUtil::Rectangle<float> rdest;
float u1, v1, u2, v2; float u1, v1, u2, v2, G;
} tex_sub_quad_data; } tex_sub_quad_data;
struct struct
@ -519,7 +519,8 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
int SourceHeight, int SourceHeight,
ID3D11PixelShader* PShader, ID3D11PixelShader* PShader,
ID3D11VertexShader* Vshader, ID3D11VertexShader* Vshader,
ID3D11InputLayout* layout) ID3D11InputLayout* layout,
float Gamma)
{ {
float sw = 1.0f /(float) SourceWidth; float sw = 1.0f /(float) SourceWidth;
float sh = 1.0f /(float) SourceHeight; float sh = 1.0f /(float) SourceHeight;
@ -527,18 +528,19 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
float u2 = ((float)rSource->right) * sw; float u2 = ((float)rSource->right) * sw;
float v1 = ((float)rSource->top) * sh; float v1 = ((float)rSource->top) * sh;
float v2 = ((float)rSource->bottom) * sh; float v2 = ((float)rSource->bottom) * sh;
float G = 1.0f / Gamma;
STQVertex coords[4] = { STQVertex coords[4] = {
{-1.0f, 1.0f, 0.0f, u1, v1}, {-1.0f, 1.0f, 0.0f, u1, v1, G},
{ 1.0f, 1.0f, 0.0f, u2, v1}, { 1.0f, 1.0f, 0.0f, u2, v1, G},
{-1.0f,-1.0f, 0.0f, u1, v2}, {-1.0f,-1.0f, 0.0f, u1, v2, G},
{ 1.0f,-1.0f, 0.0f, u2, v2}, { 1.0f,-1.0f, 0.0f, u2, v2, G},
}; };
// only upload the data to VRAM if it changed // only upload the data to VRAM if it changed
if (stq_observer || if (stq_observer ||
tex_quad_data.u1 != u1 || tex_quad_data.v1 != v1 || tex_quad_data.u1 != u1 || tex_quad_data.v1 != v1 ||
tex_quad_data.u2 != u2 || tex_quad_data.v2 != v2) tex_quad_data.u2 != u2 || tex_quad_data.v2 != v2 || tex_quad_data.G != G)
{ {
stq_offset = util_vbuf->AppendData(coords, sizeof(coords), sizeof(STQVertex)); stq_offset = util_vbuf->AppendData(coords, sizeof(coords), sizeof(STQVertex));
stq_observer = false; stq_observer = false;
@ -547,6 +549,7 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
tex_quad_data.v1 = v1; tex_quad_data.v1 = v1;
tex_quad_data.u2 = u2; tex_quad_data.u2 = u2;
tex_quad_data.v2 = v2; tex_quad_data.v2 = v2;
tex_quad_data.G = G;
} }
UINT stride = sizeof(STQVertex); UINT stride = sizeof(STQVertex);
UINT offset = 0; UINT offset = 0;
@ -571,7 +574,8 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
const MathUtil::Rectangle<float>* rDest, const MathUtil::Rectangle<float>* rDest,
ID3D11PixelShader* PShader, ID3D11PixelShader* PShader,
ID3D11VertexShader* Vshader, ID3D11VertexShader* Vshader,
ID3D11InputLayout* layout) ID3D11InputLayout* layout,
float Gamma)
{ {
float sw = 1.0f /(float) SourceWidth; float sw = 1.0f /(float) SourceWidth;
float sh = 1.0f /(float) SourceHeight; float sh = 1.0f /(float) SourceHeight;
@ -579,19 +583,20 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
float u2 = (rSource->right ) * sw; float u2 = (rSource->right ) * sw;
float v1 = (rSource->top ) * sh; float v1 = (rSource->top ) * sh;
float v2 = (rSource->bottom) * sh; float v2 = (rSource->bottom) * sh;
float G = 1.0f / Gamma;
STSQVertex coords[4] = { STSQVertex coords[4] = {
{ rDest->left , rDest->bottom, 0.0f, u1, v1}, { rDest->left , rDest->bottom, 0.0f, u1, v1, G},
{ rDest->right, rDest->bottom, 0.0f, u2, v1}, { rDest->right, rDest->bottom, 0.0f, u2, v1, G},
{ rDest->left , rDest->top , 0.0f, u1, v2}, { rDest->left , rDest->top , 0.0f, u1, v2, G},
{ rDest->right, rDest->top , 0.0f, u2, v2}, { rDest->right, rDest->top , 0.0f, u2, v2, G},
}; };
// only upload the data to VRAM if it changed // only upload the data to VRAM if it changed
if (stsq_observer || if (stsq_observer ||
memcmp(rDest, &tex_sub_quad_data.rdest, sizeof(rDest)) != 0 || memcmp(rDest, &tex_sub_quad_data.rdest, sizeof(rDest)) != 0 ||
tex_sub_quad_data.u1 != u1 || tex_sub_quad_data.v1 != v1 || tex_sub_quad_data.u1 != u1 || tex_sub_quad_data.v1 != v1 ||
tex_sub_quad_data.u2 != u2 || tex_sub_quad_data.v2 != v2) tex_sub_quad_data.u2 != u2 || tex_sub_quad_data.v2 != v2 || tex_sub_quad_data.G != G)
{ {
stsq_offset = util_vbuf->AppendData(coords, sizeof(coords), sizeof(STSQVertex)); stsq_offset = util_vbuf->AppendData(coords, sizeof(coords), sizeof(STSQVertex));
stsq_observer = false; stsq_observer = false;
@ -600,6 +605,7 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
tex_sub_quad_data.v1 = v1; tex_sub_quad_data.v1 = v1;
tex_sub_quad_data.u2 = u2; tex_sub_quad_data.u2 = u2;
tex_sub_quad_data.v2 = v2; tex_sub_quad_data.v2 = v2;
tex_sub_quad_data.G = G;
memcpy(&tex_sub_quad_data.rdest, &rDest, sizeof(rDest)); memcpy(&tex_sub_quad_data.rdest, &rDest, sizeof(rDest));
} }
UINT stride = sizeof(STSQVertex); UINT stride = sizeof(STSQVertex);

View File

@ -70,7 +70,8 @@ namespace D3D
int SourceHeight, int SourceHeight,
ID3D11PixelShader* PShader, ID3D11PixelShader* PShader,
ID3D11VertexShader* VShader, ID3D11VertexShader* VShader,
ID3D11InputLayout* layout); ID3D11InputLayout* layout,
float Gamma = 1.0f);
void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture, void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
const MathUtil::Rectangle<float>* rSource, const MathUtil::Rectangle<float>* rSource,
int SourceWidth, int SourceWidth,
@ -78,7 +79,8 @@ namespace D3D
const MathUtil::Rectangle<float>* rDest, const MathUtil::Rectangle<float>* rDest,
ID3D11PixelShader* PShader, ID3D11PixelShader* PShader,
ID3D11VertexShader* Vshader, ID3D11VertexShader* Vshader,
ID3D11InputLayout* layout); ID3D11InputLayout* layout,
float Gamma = 1.0f);
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout); void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout);
void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2); void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2);
} }

View File

@ -144,7 +144,7 @@ FramebufferManager::~FramebufferManager()
SAFE_RELEASE(m_efb.resolved_depth_tex); SAFE_RELEASE(m_efb.resolved_depth_tex);
} }
void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
{ {
// TODO // TODO
PanicAlert("CopyToRealXFB not implemented, yet\n"); PanicAlert("CopyToRealXFB not implemented, yet\n");
@ -187,7 +187,7 @@ void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
PanicAlert("RealXFB not implemented, yet\n"); PanicAlert("RealXFB not implemented, yet\n");
} }
void XFBSource::CopyEFB() void XFBSource::CopyEFB(float Gamma)
{ {
// Copy EFB data to XFB and restore render target again // Copy EFB data to XFB and restore render target again
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight); const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight);
@ -199,7 +199,7 @@ void XFBSource::CopyEFB()
D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), sourceRc.AsRECT(), D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), sourceRc.AsRECT(),
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
PixelShaderCache::GetColorCopyProgram(true), VertexShaderCache::GetSimpleVertexShader(), PixelShaderCache::GetColorCopyProgram(true), VertexShaderCache::GetSimpleVertexShader(),
VertexShaderCache::GetSimpleInputLayout()); VertexShaderCache::GetSimpleInputLayout(),Gamma);
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(),
FramebufferManager::GetEFBDepthTexture()->GetDSV()); FramebufferManager::GetEFBDepthTexture()->GetDSV());

View File

@ -62,7 +62,7 @@ struct XFBSource : public XFBSourceBase
void Draw(const MathUtil::Rectangle<float> &sourcerc, void Draw(const MathUtil::Rectangle<float> &sourcerc,
const MathUtil::Rectangle<float> &drawrc, int width, int height) const; const MathUtil::Rectangle<float> &drawrc, int width, int height) const;
void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight); void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
void CopyEFB(); void CopyEFB(float Gamma);
D3DTexture2D* const tex; D3DTexture2D* const tex;
}; };
@ -87,7 +87,7 @@ private:
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height); XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height);
void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc); void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc);
void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma);
static struct Efb static struct Efb
{ {

View File

@ -559,7 +559,16 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map); D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map);
float val = *(float*)map.pData; float val = *(float*)map.pData;
u32 ret = ((u32)(val * 0xffffff)); u32 ret = 0;
if(bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
{
// if Z is in 16 bit format yo must return a 16 bit integer
ret = ((u32)(val * 0xffff));
}
else
{
ret = ((u32)(val * 0xffffff));
}
D3D::context->Unmap(read_tex, 0); D3D::context->Unmap(read_tex, 0);
// TODO: in RE0 this value is often off by one in Video_DX9 (where this code is derived from), which causes lighting to disappear // TODO: in RE0 this value is often off by one in Video_DX9 (where this code is derived from), which causes lighting to disappear
@ -574,12 +583,28 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
// read the data from system memory // read the data from system memory
D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map); D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map);
u32 ret = *(u32*)map.pData; u32 ret = 0;
if(map.pData)
ret = *(u32*)map.pData;
D3D::context->Unmap(read_tex, 0); D3D::context->Unmap(read_tex, 0);
// check what to do with the alpha channel (GX_PokeAlphaRead) // check what to do with the alpha channel (GX_PokeAlphaRead)
PixelEngine::UPEAlphaReadReg alpha_read_mode; PixelEngine::UPEAlphaReadReg alpha_read_mode;
PixelEngine::Read16((u16&)alpha_read_mode, PE_DSTALPHACONF); PixelEngine::Read16((u16&)alpha_read_mode, PE_DSTALPHACONF);
if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)
{
ret = RGBA8ToRGBA6ToRGBA8(ret);
}
else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
{
ret = RGBA8ToRGB565ToRGB8(ret);
}
if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24)
{
ret |= 0xFF000000;
}
if(alpha_read_mode.ReadMode == 2) return ret; // GX_READ_NONE if(alpha_read_mode.ReadMode == 2) return ret; // GX_READ_NONE
else if(alpha_read_mode.ReadMode == 1) return (ret | 0xFF000000); // GX_READ_FF else if(alpha_read_mode.ReadMode == 1) return (ret | 0xFF000000); // GX_READ_FF
else /*if(alpha_read_mode.ReadMode == 0)*/ return (ret & 0x00FFFFFF); // GX_READ_00 else /*if(alpha_read_mode.ReadMode == 0)*/ return (ret & 0x00FFFFFF); // GX_READ_00
@ -775,7 +800,7 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle
// This function has the final picture. We adjust the aspect ratio here. // This function has the final picture. We adjust the aspect ratio here.
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc) void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
{ {
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight) if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
{ {
@ -880,7 +905,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
// TODO: Improve sampling algorithm for the pixel shader so that we can use the multisampled EFB texture as source // TODO: Improve sampling algorithm for the pixel shader so that we can use the multisampled EFB texture as source
D3DTexture2D* read_texture = FramebufferManager::GetResolvedEFBColorTexture(); D3DTexture2D* read_texture = FramebufferManager::GetResolvedEFBColorTexture();
D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), PixelShaderCache::GetColorCopyProgram(false),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), PixelShaderCache::GetColorCopyProgram(false),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout(), Gamma);
} }
// done with drawing the game stuff, good moment to save a screenshot // done with drawing the game stuff, good moment to save a screenshot
if (s_bScreenshot) if (s_bScreenshot)

View File

@ -33,7 +33,7 @@ public:
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc); TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc);
void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc); void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma);
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z); void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);

View File

@ -99,12 +99,14 @@ const char simple_shader_code[] = {
"{\n" "{\n"
"float4 vPosition : POSITION;\n" "float4 vPosition : POSITION;\n"
"float2 vTexCoord : TEXCOORD0;\n" "float2 vTexCoord : TEXCOORD0;\n"
"float vTexCoord1 : TEXCOORD1;\n"
"};\n" "};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0)\n" "VSOUTPUT main(float4 inPosition : POSITION,float3 inTEX0 : TEXCOORD0)\n"
"{\n" "{\n"
"VSOUTPUT OUT;\n" "VSOUTPUT OUT;\n"
"OUT.vPosition = inPosition;\n" "OUT.vPosition = inPosition;\n"
"OUT.vTexCoord = inTEX0;\n" "OUT.vTexCoord = inTEX0.xy;\n"
"OUT.vTexCoord1 = inTEX0.z;\n"
"return OUT;\n" "return OUT;\n"
"}\n" "}\n"
}; };
@ -129,7 +131,8 @@ void VertexShaderCache::Init()
const D3D11_INPUT_ELEMENT_DESC simpleelems[2] = const D3D11_INPUT_ELEMENT_DESC simpleelems[2] =
{ {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
}; };
const D3D11_INPUT_ELEMENT_DESC clearelems[2] = const D3D11_INPUT_ELEMENT_DESC clearelems[2] =
{ {

View File

@ -386,7 +386,8 @@ void drawShadedTexQuad(IDirect3DTexture9 *texture,
int DestWidth, int DestWidth,
int DestHeight, int DestHeight,
IDirect3DPixelShader9 *PShader, IDirect3DPixelShader9 *PShader,
IDirect3DVertexShader9 *Vshader) IDirect3DVertexShader9 *Vshader,
float Gamma)
{ {
float sw = 1.0f /(float) SourceWidth; float sw = 1.0f /(float) SourceWidth;
float sh = 1.0f /(float) SourceHeight; float sh = 1.0f /(float) SourceHeight;
@ -396,17 +397,18 @@ void drawShadedTexQuad(IDirect3DTexture9 *texture,
float u2=((float)rSource->right) * sw; float u2=((float)rSource->right) * sw;
float v1=((float)rSource->top) * sh; float v1=((float)rSource->top) * sh;
float v2=((float)rSource->bottom) * sh; float v2=((float)rSource->bottom) * sh;
float g = 1.0/Gamma;
struct Q2DVertex { float x,y,z,rhw,u,v,w,h,L,T,R,B; } coords[4] = { struct Q2DVertex { float x,y,z,rhw,u,v,w,h,G; } coords[4] = {
{-1.0f - dw,-1.0f + dh, 0.0f,1.0f, u1, v2, sw, sh,u1,v1,u2,v2}, {-1.0f - dw,-1.0f + dh, 0.0f,1.0f, u1, v2, sw, sh, g},
{-1.0f - dw, 1.0f + dh, 0.0f,1.0f, u1, v1, sw, sh,u1,v1,u2,v2}, {-1.0f - dw, 1.0f + dh, 0.0f,1.0f, u1, v1, sw, sh, g},
{ 1.0f - dw,-1.0f + dh, 0.0f,1.0f, u2, v2, sw, sh,u1,v1,u2,v2}, { 1.0f - dw,-1.0f + dh, 0.0f,1.0f, u2, v2, sw, sh, g},
{ 1.0f - dw, 1.0f + dh, 0.0f,1.0f, u2, v1, sw, sh,u1,v1,u2,v2} { 1.0f - dw, 1.0f + dh, 0.0f,1.0f, u2, v1, sw, sh, g}
}; };
dev->SetVertexShader(Vshader); dev->SetVertexShader(Vshader);
dev->SetPixelShader(PShader); dev->SetPixelShader(PShader);
D3D::SetTexture(0, texture); D3D::SetTexture(0, texture);
dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE4(2)); dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2));
dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex)); dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex));
RestoreShaders(); RestoreShaders();
} }
@ -419,7 +421,8 @@ void drawShadedTexSubQuad(IDirect3DTexture9 *texture,
int DestWidth, int DestWidth,
int DestHeight, int DestHeight,
IDirect3DPixelShader9 *PShader, IDirect3DPixelShader9 *PShader,
IDirect3DVertexShader9 *Vshader) IDirect3DVertexShader9 *Vshader,
float Gamma)
{ {
float sw = 1.0f /(float) SourceWidth; float sw = 1.0f /(float) SourceWidth;
float sh = 1.0f /(float) SourceHeight; float sh = 1.0f /(float) SourceHeight;
@ -429,17 +432,18 @@ void drawShadedTexSubQuad(IDirect3DTexture9 *texture,
float u2= rSource->right * sw; float u2= rSource->right * sw;
float v1= rSource->top * sh; float v1= rSource->top * sh;
float v2= rSource->bottom * sh; float v2= rSource->bottom * sh;
float g = 1.0/Gamma;
struct Q2DVertex { float x,y,z,rhw,u,v,w,h,L,T,R,B; } coords[4] = { struct Q2DVertex { float x,y,z,rhw,u,v,w,h,G; } coords[4] = {
{ rDest->left - dw , rDest->top + dh, 1.0f,1.0f, u1, v2, sw, sh,u1,v1,u2,v2}, { rDest->left - dw , rDest->top + dh, 1.0f,1.0f, u1, v2, sw, sh, g},
{ rDest->left - dw , rDest->bottom + dh, 1.0f,1.0f, u1, v1, sw, sh,u1,v1,u2,v2}, { rDest->left - dw , rDest->bottom + dh, 1.0f,1.0f, u1, v1, sw, sh, g},
{ rDest->right - dw , rDest->top + dh, 1.0f,1.0f, u2, v2, sw, sh,u1,v1,u2,v2}, { rDest->right - dw , rDest->top + dh, 1.0f,1.0f, u2, v2, sw, sh, g},
{ rDest->right - dw , rDest->bottom + dh, 1.0f,1.0f, u2, v1, sw, sh,u1,v1,u2,v2} { rDest->right - dw , rDest->bottom + dh, 1.0f,1.0f, u2, v1, sw, sh, g}
}; };
dev->SetVertexShader(Vshader); dev->SetVertexShader(Vshader);
dev->SetPixelShader(PShader); dev->SetPixelShader(PShader);
D3D::SetTexture(0, texture); D3D::SetTexture(0, texture);
dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE4(2)); dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2));
dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex)); dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex));
RestoreShaders(); RestoreShaders();
} }

View File

@ -67,7 +67,8 @@ namespace D3D
int DestWidth, int DestWidth,
int DestHeight, int DestHeight,
IDirect3DPixelShader9 *PShader, IDirect3DPixelShader9 *PShader,
IDirect3DVertexShader9 *Vshader); IDirect3DVertexShader9 *Vshader,
float Gamma = 1.0f);
void drawShadedTexSubQuad(IDirect3DTexture9 *texture, void drawShadedTexSubQuad(IDirect3DTexture9 *texture,
const MathUtil::Rectangle<float> *rSource, const MathUtil::Rectangle<float> *rSource,
int SourceWidth, int SourceWidth,
@ -76,7 +77,8 @@ namespace D3D
int DestWidth, int DestWidth,
int DestHeight, int DestHeight,
IDirect3DPixelShader9 *PShader, IDirect3DPixelShader9 *PShader,
IDirect3DVertexShader9 *Vshader); IDirect3DVertexShader9 *Vshader,
float Gamma = 1.0f);
void drawClearQuad(u32 Color, float z, IDirect3DPixelShader9 *PShader, IDirect3DVertexShader9 *Vshader); void drawClearQuad(u32 Color, float z, IDirect3DPixelShader9 *PShader, IDirect3DVertexShader9 *Vshader);
void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2); void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2);

View File

@ -183,7 +183,7 @@ void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
TextureConverter::DecodeToTexture(xfbAddr, fbWidth, fbHeight, texture); TextureConverter::DecodeToTexture(xfbAddr, fbWidth, fbHeight, texture);
} }
void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
{ {
u8* xfb_in_ram = Memory_GetPtr(xfbAddr); u8* xfb_in_ram = Memory_GetPtr(xfbAddr);
if (!xfb_in_ram) if (!xfb_in_ram)
@ -193,10 +193,10 @@ void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c
} }
TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc); TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc);
TextureConverter::EncodeToRamYUYV(GetEFBColorTexture(), targetRc, xfb_in_ram, fbWidth, fbHeight); TextureConverter::EncodeToRamYUYV(GetEFBColorTexture(), targetRc, xfb_in_ram, fbWidth, fbHeight,Gamma);
} }
void XFBSource::CopyEFB() void XFBSource::CopyEFB(float Gamma)
{ {
// Copy EFB data to XFB and restore render target again // Copy EFB data to XFB and restore render target again
LPDIRECT3DSURFACE9 Rendersurf = NULL; LPDIRECT3DSURFACE9 Rendersurf = NULL;
@ -230,7 +230,8 @@ void XFBSource::CopyEFB()
texWidth, texWidth,
texHeight, texHeight,
PixelShaderCache::GetColorCopyProgram( g_ActiveConfig.iMultisampleMode), PixelShaderCache::GetColorCopyProgram( g_ActiveConfig.iMultisampleMode),
VertexShaderCache::GetSimpleVertexShader( g_ActiveConfig.iMultisampleMode)); VertexShaderCache::GetSimpleVertexShader( g_ActiveConfig.iMultisampleMode),
Gamma);
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);

View File

@ -58,7 +58,7 @@ struct XFBSource : public XFBSourceBase
void Draw(const MathUtil::Rectangle<float> &sourcerc, void Draw(const MathUtil::Rectangle<float> &sourcerc,
const MathUtil::Rectangle<float> &drawrc, int width, int height) const; const MathUtil::Rectangle<float> &drawrc, int width, int height) const;
void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight); void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
void CopyEFB(); void CopyEFB(float Gamma);
LPDIRECT3DTEXTURE9 const texture; LPDIRECT3DTEXTURE9 const texture;
}; };
@ -89,7 +89,7 @@ private:
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height); XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height);
void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc); void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc);
void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma);
static struct Efb static struct Efb
{ {

View File

@ -124,20 +124,21 @@ static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConv
switch(SSAAMode % MAX_SSAA_SHADERS) switch(SSAAMode % MAX_SSAA_SHADERS)
{ {
case 0: // 1 Sample case 0: // 1 Sample
WRITE(p, "in float2 uv0 : TEXCOORD0){\n" WRITE(p, "in float2 uv0 : TEXCOORD0,\n"
"float4 texcol = tex2D(samp0,uv0);\n"); "in float uv1 : TEXCOORD1){\n"
"float4 texcol = tex2D(samp0,uv0.xy);\n");
break; break;
case 1: // 1 Samples SSAA case 1: // 1 Samples SSAA
WRITE(p, "in float4 uv0 : TEXCOORD0,\n" WRITE(p, "in float4 uv0 : TEXCOORD0,\n"
"in float4 uv1 : TEXCOORD1){\n" "in float uv1 : TEXCOORD1){\n"
"float4 texcol = tex2D(samp0,uv0.xy);\n"); "float4 texcol = tex2D(samp0,uv0.xy);\n");
break; break;
case 2: // 4 Samples SSAA case 2: // 4 Samples SSAA
WRITE(p, "in float4 uv0 : TEXCOORD0,\n" WRITE(p, "in float4 uv0 : TEXCOORD0,\n"
"in float4 uv1 : TEXCOORD1,\n" "in float uv1 : TEXCOORD1,\n"
"in float4 uv2 : TEXCOORD2,\n" "in float4 uv2 : TEXCOORD2,\n"
"in float4 uv3 : TEXCOORD3){\n" "in float4 uv3 : TEXCOORD3){\n"
"float4 texcol = (tex2D(samp0,uv1.xy) + tex2D(samp0,uv1.wz) + tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz))*0.25f;\n"); "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n");
break; break;
} }
@ -155,9 +156,17 @@ static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConv
"texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n"); "texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n");
break; break;
} }
//Apply Gamma Correction
if((depthConversionType % PixelShaderCache::NUM_DEPTH_CONVERSION_TYPES) == PixelShaderCache::DEPTH_CONVERSION_TYPE_NONE)
{
WRITE(p, "texcol = pow(texcol,uv1.xxxx);\n");
}
if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) if(copyMatrixType == COPY_TYPE_MATRIXCOLOR)
{
WRITE(p, "ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"); WRITE(p, "ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n");
}
else else
WRITE(p, "ocol0 = texcol;\n"); WRITE(p, "ocol0 = texcol;\n");

View File

@ -643,10 +643,19 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
val += ((float)(z & 0xFF)) * ffrac; val += ((float)(z & 0xFF)) * ffrac;
break; break;
}; };
z = ((u32)(val * 0xffffff));
pSystemBuf->UnlockRect(); pSystemBuf->UnlockRect();
// TODO: in RE0 this value is often off by one, which causes lighting to disappear // TODO: in RE0 this value is often off by one, which causes lighting to disappear
if(bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
{
// if Z is in 16 bit format yo must return a 16 bit integer
z = ((u32)(val * 0xffff));
}
else
{
z = ((u32)(val * 0xffffff));
}
return z; return z;
} }
else if(type == PEEK_COLOR) else if(type == PEEK_COLOR)
@ -669,9 +678,21 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
// check what to do with the alpha channel (GX_PokeAlphaRead) // check what to do with the alpha channel (GX_PokeAlphaRead)
PixelEngine::UPEAlphaReadReg alpha_read_mode; PixelEngine::UPEAlphaReadReg alpha_read_mode;
PixelEngine::Read16((u16&)alpha_read_mode, PE_DSTALPHACONF); PixelEngine::Read16((u16&)alpha_read_mode, PE_DSTALPHACONF);
if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)
{
ret = RGBA8ToRGBA6ToRGBA8(ret);
}
else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
{
ret = RGBA8ToRGB565ToRGB8(ret);
}
if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24)
{
ret |= 0xFF000000;
}
if(alpha_read_mode.ReadMode == 2) return ret; // GX_READ_NONE if(alpha_read_mode.ReadMode == 2) return ret; // GX_READ_NONE
else if(alpha_read_mode.ReadMode == 1) return (ret | 0xFF000000); // GX_READ_FF else if(alpha_read_mode.ReadMode == 1) return (ret | 0xFF000000); // GX_READ_FF
else /*if(alpha_read_mode.ReadMode == 0)*/ return (ret & 0x00FFFFFF); // GX_READ_00 else return (ret & 0x00FFFFFF); // GX_READ_00
} }
else //if(type == POKE_COLOR) else //if(type == POKE_COLOR)
{ {
@ -865,7 +886,7 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle
} }
// This function has the final picture. We adjust the aspect ratio here. // This function has the final picture. We adjust the aspect ratio here.
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc) void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
{ {
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight) if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
{ {
@ -1015,7 +1036,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
{ {
TargetRectangle targetRc = ConvertEFBRectangle(rc); TargetRectangle targetRc = ConvertEFBRectangle(rc);
LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBColorTexture(); LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBColorTexture();
D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(),Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),Width,Height,PixelShaderCache::GetColorCopyProgram(g_Config.iMultisampleMode),VertexShaderCache::GetSimpleVertexShader(g_Config.iMultisampleMode)); D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(),Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),Width,Height,PixelShaderCache::GetColorCopyProgram(g_Config.iMultisampleMode),VertexShaderCache::GetSimpleVertexShader(g_Config.iMultisampleMode),Gamma);
} }
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);

View File

@ -33,7 +33,7 @@ public:
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc); TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc);
void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc); void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma);
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z); void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);

View File

@ -63,11 +63,14 @@ void CreateRgbToYuyvProgram()
"uniform sampler samp0 : register(s0);\n" "uniform sampler samp0 : register(s0);\n"
"void main(\n" "void main(\n"
" out float4 ocol0 : COLOR0,\n" " out float4 ocol0 : COLOR0,\n"
" in float2 uv0 : TEXCOORD0)\n" " in float2 uv0 : TEXCOORD0,\n"
" in float uv1 : TEXCOORD1)\n"
"{\n" "{\n"
" float2 uv1 = float2((uv0.x + 1.0f)/ blkDims.z, uv0.y / blkDims.w);\n" " float2 uv1 = float2((uv0.x + 1.0f)/ blkDims.z, uv0.y / blkDims.w);\n"
" float3 c0 = tex2D(samp0, uv0.xy / blkDims.zw).rgb;\n" " float3 c0 = tex2D(samp0, uv0.xy / blkDims.zw).rgb;\n"
" float3 c1 = tex2D(samp0, uv1).rgb;\n" " float3 c1 = tex2D(samp0, uv1).rgb;\n"
" c0 = pow(c0,uv1.xxx);\n"
" c1 = pow(c1,uv1.xxx);\n"
" float3 y_const = float3(0.257f,0.504f,0.098f);\n" " float3 y_const = float3(0.257f,0.504f,0.098f);\n"
" float3 u_const = float3(-0.148f,-0.291f,0.439f);\n" " float3 u_const = float3(-0.148f,-0.291f,0.439f);\n"
" float3 v_const = float3(0.439f,-0.368f,-0.071f);\n" " float3 v_const = float3(0.439f,-0.368f,-0.071f);\n"
@ -204,7 +207,7 @@ void Shutdown()
} }
void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc,
u8* destAddr, int dstWidth, int dstHeight, int readStride, bool toTexture, bool linearFilter) u8* destAddr, int dstWidth, int dstHeight, int readStride, bool toTexture, bool linearFilter,float Gamma)
{ {
HRESULT hr; HRESULT hr;
u32 index =0; u32 index =0;
@ -376,7 +379,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
g_renderer->ResetAPIState(); g_renderer->ResetAPIState();
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0,1.0f);
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
g_renderer->RestoreAPIState(); g_renderer->RestoreAPIState();
@ -439,7 +442,7 @@ u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture, u32 So
cacheBytes = 64; cacheBytes = 64;
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0,1.0f);
u64 hash = 0; u64 hash = 0;
if (g_ActiveConfig.bEFBCopyCacheEnable) if (g_ActiveConfig.bEFBCopyCacheEnable)
{ {
@ -454,7 +457,7 @@ u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture, u32 So
return hash; return hash;
} }
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight) void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight,float Gamma)
{ {
TextureConversionShader::SetShaderParameters( TextureConversionShader::SetShaderParameters(
(float)dstWidth, (float)dstWidth,
@ -466,7 +469,7 @@ void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourc
(float)Renderer::GetFullTargetWidth(), (float)Renderer::GetFullTargetWidth(),
(float)Renderer::GetFullTargetHeight()); (float)Renderer::GetFullTargetHeight());
g_renderer->ResetAPIState(); g_renderer->ResetAPIState();
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false); EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false,Gamma);
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
g_renderer->RestoreAPIState(); g_renderer->RestoreAPIState();

View File

@ -36,7 +36,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt,
u32 copyfmt, int bScaleByHalf, const EFBRectangle& source); u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc,
u8* destAddr, int dstWidth, int dstHeight); u8* destAddr, int dstWidth, int dstHeight,float Gamma);
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE9 destTexture); void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE9 destTexture);

View File

@ -99,12 +99,14 @@ void VertexShaderCache::Init()
"{\n" "{\n"
"float4 vPosition : POSITION;\n" "float4 vPosition : POSITION;\n"
"float2 vTexCoord : TEXCOORD0;\n" "float2 vTexCoord : TEXCOORD0;\n"
"float vTexCoord1 : TEXCOORD1;\n"
"};\n" "};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0)\n" "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n"
"{\n" "{\n"
"VSOUTPUT OUT;\n" "VSOUTPUT OUT;\n"
"OUT.vPosition = inPosition;\n" "OUT.vPosition = inPosition;\n"
"OUT.vTexCoord = inTEX0;\n" "OUT.vTexCoord = inTEX0;\n"
"OUT.vTexCoord1 = inTEX2;\n"
"return OUT;\n" "return OUT;\n"
"}\n"); "}\n");
@ -129,9 +131,9 @@ void VertexShaderCache::Init()
"{\n" "{\n"
"float4 vPosition : POSITION;\n" "float4 vPosition : POSITION;\n"
"float4 vTexCoord : TEXCOORD0;\n" "float4 vTexCoord : TEXCOORD0;\n"
"float4 vTexCoord1 : TEXCOORD1;\n" "float vTexCoord1 : TEXCOORD1;\n"
"};\n" "};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float4 inTEX2 : TEXCOORD2)\n" "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n"
"{\n" "{\n"
"VSOUTPUT OUT;" "VSOUTPUT OUT;"
"OUT.vPosition = inPosition;\n" "OUT.vPosition = inPosition;\n"
@ -145,18 +147,18 @@ void VertexShaderCache::Init()
"{\n" "{\n"
"float4 vPosition : POSITION;\n" "float4 vPosition : POSITION;\n"
"float4 vTexCoord : TEXCOORD0;\n" "float4 vTexCoord : TEXCOORD0;\n"
"float4 vTexCoord1 : TEXCOORD1;\n" "float vTexCoord1 : TEXCOORD1;\n"
"float4 vTexCoord2 : TEXCOORD2;\n" "float4 vTexCoord2 : TEXCOORD2;\n"
"float4 vTexCoord3 : TEXCOORD3;\n" "float4 vTexCoord3 : TEXCOORD3;\n"
"};\n" "};\n"
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float4 inTEX2 : TEXCOORD2)\n" "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n"
"{\n" "{\n"
"VSOUTPUT OUT;" "VSOUTPUT OUT;"
"OUT.vPosition = inPosition;\n" "OUT.vPosition = inPosition;\n"
"OUT.vTexCoord = inTEX0.xyyx;\n" "OUT.vTexCoord = inTEX0.xyyx;\n"
"OUT.vTexCoord1 = inTEX0.xyyx + (float4(-1.0f,-0.5f, 1.0f,-0.5f) * inTEX1.xyyx);\n" "OUT.vTexCoord1 = inTEX2.x;\n"
"OUT.vTexCoord2 = inTEX0.xyyx + (float4( 1.0f, 0.5f,-1.0f, 0.5f) * inTEX1.xyyx);\n" "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-1.0f,-0.5f, 1.0f,-0.5f) * inTEX1.xyyx);\n"
"OUT.vTexCoord3 = inTEX2;\n" "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 1.0f, 0.5f,-1.0f, 0.5f) * inTEX1.xyyx);\n"
"return OUT;\n" "return OUT;\n"
"}\n"); "}\n");
SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg));

View File

@ -260,7 +260,7 @@ GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc)
} }
} }
void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
{ {
u8* xfb_in_ram = Memory_GetPtr(xfbAddr); u8* xfb_in_ram = Memory_GetPtr(xfbAddr);
if (!xfb_in_ram) if (!xfb_in_ram)
@ -322,7 +322,7 @@ void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
TextureConverter::DecodeToTexture(xfbAddr, fbWidth, fbHeight, texture); TextureConverter::DecodeToTexture(xfbAddr, fbWidth, fbHeight, texture);
} }
void XFBSource::CopyEFB() void XFBSource::CopyEFB(float Gamma)
{ {
// Copy EFB data to XFB and restore render target again // Copy EFB data to XFB and restore render target again

View File

@ -58,7 +58,7 @@ struct XFBSource : public XFBSourceBase
XFBSource(GLuint tex) : texture(tex) {} XFBSource(GLuint tex) : texture(tex) {}
~XFBSource() { glDeleteTextures(1, &texture); } ~XFBSource() { glDeleteTextures(1, &texture); }
void CopyEFB(); void CopyEFB(float Gamma);
void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight); void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
void Draw(const MathUtil::Rectangle<float> &sourcerc, void Draw(const MathUtil::Rectangle<float> &sourcerc,
const MathUtil::Rectangle<float> &drawrc, int width, int height) const; const MathUtil::Rectangle<float> &drawrc, int width, int height) const;
@ -99,7 +99,7 @@ private:
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height); XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height);
void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc); void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc);
void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma);
static int m_targetWidth; static int m_targetWidth;
static int m_targetHeight; static int m_targetHeight;

View File

@ -443,7 +443,7 @@ Renderer::Renderer()
glLoadIdentity(); glLoadIdentity();
glShadeModel(GL_SMOOTH); glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f); glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
@ -725,7 +725,16 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
// Scale the 32-bit value returned by glReadPixels to a 24-bit // Scale the 32-bit value returned by glReadPixels to a 24-bit
// value (GC uses a 24-bit Z-buffer). // value (GC uses a 24-bit Z-buffer).
// TODO: in RE0 this value is often off by one, which causes lighting to disappear // TODO: in RE0 this value is often off by one, which causes lighting to disappear
return z >> 8; if(bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
{
// if Z is in 16 bit format yo must return a 16 bit integer
z = z >> 16;
}
else
{
z = z >> 8;
}
return z;
} }
case POKE_Z: case POKE_Z:
@ -759,6 +768,19 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
// check what to do with the alpha channel (GX_PokeAlphaRead) // check what to do with the alpha channel (GX_PokeAlphaRead)
PixelEngine::UPEAlphaReadReg alpha_read_mode; PixelEngine::UPEAlphaReadReg alpha_read_mode;
PixelEngine::Read16((u16&)alpha_read_mode, PE_DSTALPHACONF); PixelEngine::Read16((u16&)alpha_read_mode, PE_DSTALPHACONF);
if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)
{
color = RGBA8ToRGBA6ToRGBA8(color);
}
else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
{
color = RGBA8ToRGB565ToRGB8(color);
}
if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24)
{
color |= 0xFF000000;
}
if(alpha_read_mode.ReadMode == 2) return color; // GX_READ_NONE if(alpha_read_mode.ReadMode == 2) return color; // GX_READ_NONE
else if(alpha_read_mode.ReadMode == 1) return (color | 0xFF000000); // GX_READ_FF else if(alpha_read_mode.ReadMode == 1) return (color | 0xFF000000); // GX_READ_FF
else /*if(alpha_read_mode.ReadMode == 0)*/ return (color & 0x00FFFFFF); // GX_READ_00 else /*if(alpha_read_mode.ReadMode == 0)*/ return (color & 0x00FFFFFF); // GX_READ_00
@ -926,7 +948,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
} }
// This function has the final picture. We adjust the aspect ratio here. // This function has the final picture. We adjust the aspect ratio here.
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc) void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
{ {
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight) if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
{ {

View File

@ -35,7 +35,7 @@ public:
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc); TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc);
void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc); void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma);
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z); void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);