mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 06:39:46 -06:00
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:
@ -430,20 +430,20 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
|
||||
ID3D11SamplerState* linear_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; } STSQVertex;
|
||||
typedef struct { float x,y,z,u,v,w; } STQVertex;
|
||||
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; } ColVertex;
|
||||
|
||||
struct
|
||||
{
|
||||
float u1, v1, u2, v2;
|
||||
float u1, v1, u2, v2, G;
|
||||
} tex_quad_data;
|
||||
|
||||
struct
|
||||
{
|
||||
MathUtil::Rectangle<float> rdest;
|
||||
float u1, v1, u2, v2;
|
||||
float u1, v1, u2, v2, G;
|
||||
} tex_sub_quad_data;
|
||||
|
||||
struct
|
||||
@ -519,7 +519,8 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
|
||||
int SourceHeight,
|
||||
ID3D11PixelShader* PShader,
|
||||
ID3D11VertexShader* Vshader,
|
||||
ID3D11InputLayout* layout)
|
||||
ID3D11InputLayout* layout,
|
||||
float Gamma)
|
||||
{
|
||||
float sw = 1.0f /(float) SourceWidth;
|
||||
float sh = 1.0f /(float) SourceHeight;
|
||||
@ -527,18 +528,19 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
|
||||
float u2 = ((float)rSource->right) * sw;
|
||||
float v1 = ((float)rSource->top) * sh;
|
||||
float v2 = ((float)rSource->bottom) * sh;
|
||||
float G = 1.0f / Gamma;
|
||||
|
||||
STQVertex coords[4] = {
|
||||
{-1.0f, 1.0f, 0.0f, u1, v1},
|
||||
{ 1.0f, 1.0f, 0.0f, u2, v1},
|
||||
{-1.0f,-1.0f, 0.0f, u1, v2},
|
||||
{ 1.0f,-1.0f, 0.0f, u2, v2},
|
||||
{-1.0f, 1.0f, 0.0f, u1, v1, G},
|
||||
{ 1.0f, 1.0f, 0.0f, u2, v1, G},
|
||||
{-1.0f,-1.0f, 0.0f, u1, v2, G},
|
||||
{ 1.0f,-1.0f, 0.0f, u2, v2, G},
|
||||
};
|
||||
|
||||
// only upload the data to VRAM if it changed
|
||||
if (stq_observer ||
|
||||
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_observer = false;
|
||||
@ -547,6 +549,7 @@ void drawShadedTexQuad(ID3D11ShaderResourceView* texture,
|
||||
tex_quad_data.v1 = v1;
|
||||
tex_quad_data.u2 = u2;
|
||||
tex_quad_data.v2 = v2;
|
||||
tex_quad_data.G = G;
|
||||
}
|
||||
UINT stride = sizeof(STQVertex);
|
||||
UINT offset = 0;
|
||||
@ -571,7 +574,8 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
||||
const MathUtil::Rectangle<float>* rDest,
|
||||
ID3D11PixelShader* PShader,
|
||||
ID3D11VertexShader* Vshader,
|
||||
ID3D11InputLayout* layout)
|
||||
ID3D11InputLayout* layout,
|
||||
float Gamma)
|
||||
{
|
||||
float sw = 1.0f /(float) SourceWidth;
|
||||
float sh = 1.0f /(float) SourceHeight;
|
||||
@ -579,19 +583,20 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
||||
float u2 = (rSource->right ) * sw;
|
||||
float v1 = (rSource->top ) * sh;
|
||||
float v2 = (rSource->bottom) * sh;
|
||||
float G = 1.0f / Gamma;
|
||||
|
||||
STSQVertex coords[4] = {
|
||||
{ rDest->left , rDest->bottom, 0.0f, u1, v1},
|
||||
{ rDest->right, rDest->bottom, 0.0f, u2, v1},
|
||||
{ rDest->left , rDest->top , 0.0f, u1, v2},
|
||||
{ rDest->right, rDest->top , 0.0f, u2, v2},
|
||||
{ rDest->left , rDest->bottom, 0.0f, u1, v1, G},
|
||||
{ rDest->right, rDest->bottom, 0.0f, u2, v1, G},
|
||||
{ rDest->left , rDest->top , 0.0f, u1, v2, G},
|
||||
{ rDest->right, rDest->top , 0.0f, u2, v2, G},
|
||||
};
|
||||
|
||||
// only upload the data to VRAM if it changed
|
||||
if (stsq_observer ||
|
||||
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.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_observer = false;
|
||||
@ -600,6 +605,7 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
||||
tex_sub_quad_data.v1 = v1;
|
||||
tex_sub_quad_data.u2 = u2;
|
||||
tex_sub_quad_data.v2 = v2;
|
||||
tex_sub_quad_data.G = G;
|
||||
memcpy(&tex_sub_quad_data.rdest, &rDest, sizeof(rDest));
|
||||
}
|
||||
UINT stride = sizeof(STSQVertex);
|
||||
|
@ -70,7 +70,8 @@ namespace D3D
|
||||
int SourceHeight,
|
||||
ID3D11PixelShader* PShader,
|
||||
ID3D11VertexShader* VShader,
|
||||
ID3D11InputLayout* layout);
|
||||
ID3D11InputLayout* layout,
|
||||
float Gamma = 1.0f);
|
||||
void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
|
||||
const MathUtil::Rectangle<float>* rSource,
|
||||
int SourceWidth,
|
||||
@ -78,7 +79,8 @@ namespace D3D
|
||||
const MathUtil::Rectangle<float>* rDest,
|
||||
ID3D11PixelShader* PShader,
|
||||
ID3D11VertexShader* Vshader,
|
||||
ID3D11InputLayout* layout);
|
||||
ID3D11InputLayout* layout,
|
||||
float Gamma = 1.0f);
|
||||
void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexShader* Vshader, ID3D11InputLayout* layout);
|
||||
void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2);
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ FramebufferManager::~FramebufferManager()
|
||||
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
|
||||
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");
|
||||
}
|
||||
|
||||
void XFBSource::CopyEFB()
|
||||
void XFBSource::CopyEFB(float Gamma)
|
||||
{
|
||||
// Copy EFB data to XFB and restore render target again
|
||||
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(),
|
||||
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(),
|
||||
PixelShaderCache::GetColorCopyProgram(true), VertexShaderCache::GetSimpleVertexShader(),
|
||||
VertexShaderCache::GetSimpleInputLayout());
|
||||
VertexShaderCache::GetSimpleInputLayout(),Gamma);
|
||||
|
||||
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(),
|
||||
FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||
|
@ -62,7 +62,7 @@ struct XFBSource : public XFBSourceBase
|
||||
void Draw(const MathUtil::Rectangle<float> &sourcerc,
|
||||
const MathUtil::Rectangle<float> &drawrc, int width, int height) const;
|
||||
void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
|
||||
void CopyEFB();
|
||||
void CopyEFB(float Gamma);
|
||||
|
||||
D3DTexture2D* const tex;
|
||||
};
|
||||
@ -87,7 +87,7 @@ private:
|
||||
XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height);
|
||||
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
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
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);
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
||||
// check what to do with the alpha channel (GX_PokeAlphaRead)
|
||||
PixelEngine::UPEAlphaReadReg alpha_read_mode;
|
||||
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
|
||||
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
|
||||
@ -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.
|
||||
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)
|
||||
{
|
||||
@ -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
|
||||
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
|
||||
if (s_bScreenshot)
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
|
||||
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);
|
||||
|
||||
|
@ -99,12 +99,14 @@ const char simple_shader_code[] = {
|
||||
"{\n"
|
||||
"float4 vPosition : POSITION;\n"
|
||||
"float2 vTexCoord : TEXCOORD0;\n"
|
||||
"float vTexCoord1 : TEXCOORD1;\n"
|
||||
"};\n"
|
||||
"VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0)\n"
|
||||
"VSOUTPUT main(float4 inPosition : POSITION,float3 inTEX0 : TEXCOORD0)\n"
|
||||
"{\n"
|
||||
"VSOUTPUT OUT;\n"
|
||||
"OUT.vPosition = inPosition;\n"
|
||||
"OUT.vTexCoord = inTEX0;\n"
|
||||
"OUT.vTexCoord = inTEX0.xy;\n"
|
||||
"OUT.vTexCoord1 = inTEX0.z;\n"
|
||||
"return OUT;\n"
|
||||
"}\n"
|
||||
};
|
||||
@ -129,7 +131,8 @@ void VertexShaderCache::Init()
|
||||
const D3D11_INPUT_ELEMENT_DESC simpleelems[2] =
|
||||
{
|
||||
{ "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] =
|
||||
{
|
||||
|
Reference in New Issue
Block a user