From 40b8db30e3e0499afa76e0299c0e7f8255bb4ce7 Mon Sep 17 00:00:00 2001 From: Nolan Check Date: Mon, 28 Mar 2011 05:42:21 +0000 Subject: [PATCH] DX11: Correct line width and point size by taking viewport rect into account. Twilight Princess map looks almost perfect except for the drop shadows around the borders: the lines are too skinny, but the corner points seem to be correct. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7418 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Src/LineGeometryShader.cpp | 24 +++++++++++++------ .../Plugin_VideoDX11/Src/LineGeometryShader.h | 3 ++- .../Src/PointGeometryShader.cpp | 16 ++++++++++--- .../Src/PointGeometryShader.h | 3 ++- .../Plugin_VideoDX11/Src/VertexManager.cpp | 8 +++++-- 5 files changed, 40 insertions(+), 14 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp index 036764ddae..03e7389295 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp @@ -31,6 +31,8 @@ union LineGSParams { FLOAT LineWidth; // In units of 1/6 of an EFB pixel FLOAT TexOffset; + FLOAT VpWidth; // Width and height of the viewport in EFB pixels + FLOAT VpHeight; }; // Constant buffers must be a multiple of 16 bytes in size. u8 pad[16]; // Pad to the next multiple of 16 bytes @@ -46,6 +48,8 @@ static const char LINE_GS_COMMON[] = "{\n" "float LineWidth;\n" "float TexOffset;\n" + "float VpWidth;\n" + "float VpHeight;\n" "} Params;\n" "}\n" @@ -65,17 +69,17 @@ static const char LINE_GS_COMMON[] = // horizontal depending the slope of the line. "float2 offset;\n" - "float2 to = input[1].pos.xy - input[0].pos.xy;\n" + "float2 to = abs(input[1].pos.xy - input[0].pos.xy);\n" // FIXME: What does real hardware do when line is at a 45-degree angle? // FIXME: Lines aren't drawn at the correct width. See Twilight Princess map. - "if (abs(to.y) > abs(to.x)) {\n" + "if (Params.VpHeight*to.y > Params.VpWidth*to.x) {\n" // Line is more tall. Extend geometry left and right. - // Lerp Params.LineWidth/2 from [0..640] to [-1..1] - "offset = float2(Params.LineWidth/640, 0);\n" + // Lerp Params.LineWidth/2 from [0..VpWidth] to [-1..1] + "offset = float2(Params.LineWidth/Params.VpWidth, 0);\n" "} else {\n" // Line is more wide. Extend geometry up and down. - // Lerp Params.LineWidth/2 from [0..528] to [1..-1] - "offset = float2(0, -Params.LineWidth/528);\n" + // Lerp Params.LineWidth/2 from [0..VpHeight] to [1..-1] + "offset = float2(0, -Params.LineWidth/Params.VpHeight);\n" "}\n" "l0.pos.xy -= offset * input[0].pos.w;\n" @@ -164,7 +168,8 @@ void LineGeometryShader::Shutdown() SAFE_RELEASE(m_paramsBuffer); } -bool LineGeometryShader::SetShader(u32 components, float lineWidth, float texOffset) +bool LineGeometryShader::SetShader(u32 components, float lineWidth, + float texOffset, float vpWidth, float vpHeight) { if (!m_ready) return false; @@ -208,8 +213,13 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth, float texOff LineGSParams params = { 0 }; params.LineWidth = lineWidth; params.TexOffset = texOffset; + params.VpWidth = vpWidth; + params.VpHeight = vpHeight; D3D::context->UpdateSubresource(m_paramsBuffer, 0, NULL, ¶ms, 0, 0); + DEBUG_LOG(VIDEO, "Line params: width %f, texOffset %f, vpWidth %f, vpHeight %f", + lineWidth, texOffset, vpWidth, vpHeight); + D3D::context->GSSetShader(shaderIt->second, NULL, 0); D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.h b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.h index 0cb43e8a75..df2ce11e9a 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.h @@ -38,7 +38,8 @@ public: void Init(); void Shutdown(); // Returns true on success, false on failure - bool SetShader(u32 components, float lineWidth, float texOffset); + bool SetShader(u32 components, float lineWidth, float texOffset, + float vpWidth, float vpHeight); private: diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp index 9ceef4561f..a7293d7c07 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp @@ -31,6 +31,8 @@ union PointGSParams { FLOAT PointSize; // In units of 1/6 of an EFB pixel FLOAT TexOffset; + FLOAT VpWidth; // Width and height of viewport in EFB pixels + FLOAT VpHeight; }; // Constant buffers must be a multiple of 16 bytes in size. u8 pad[16]; // Pad to the next multiple of 16 bytes @@ -46,6 +48,8 @@ static const char POINT_GS_COMMON[] = "{\n" "float PointSize;\n" "float TexOffset;\n" + "float VpWidth;\n" + "float VpHeight;\n" "} Params;\n" "}\n" @@ -58,8 +62,8 @@ static const char POINT_GS_COMMON[] = "VS_OUTPUT ptUR = ptLL;\n" // Offset from center to upper right vertex - // Lerp Params.PointSize/2 from [0,0..640,528] to [-1,1..1,-1] - "float2 offset = float2(Params.PointSize/640, -Params.PointSize/528) * input[0].pos.w;\n" + // Lerp Params.PointSize/2 from [0,0..VpWidth,VpHeight] to [-1,1..1,-1] + "float2 offset = float2(Params.PointSize/Params.VpWidth, -Params.PointSize/Params.VpHeight) * input[0].pos.w;\n" "ptLL.pos.xy += float2(-1,-1) * offset;\n" "ptLR.pos.xy += float2(1,-1) * offset;\n" @@ -157,7 +161,8 @@ void PointGeometryShader::Shutdown() SAFE_RELEASE(m_paramsBuffer); } -bool PointGeometryShader::SetShader(u32 components, float pointSize, float texOffset) +bool PointGeometryShader::SetShader(u32 components, float pointSize, + float texOffset, float vpWidth, float vpHeight) { if (!m_ready) return false; @@ -201,7 +206,12 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize, float texOf PointGSParams params = { 0 }; params.PointSize = pointSize; params.TexOffset = texOffset; + params.VpWidth = vpWidth; + params.VpHeight = vpHeight; D3D::context->UpdateSubresource(m_paramsBuffer, 0, NULL, ¶ms, 0, 0); + + DEBUG_LOG(VIDEO, "Point params: size %f, texOffset %f, vpWidth %f, vpHeight %f", + pointSize, texOffset, vpWidth, vpHeight); D3D::context->GSSetShader(shaderIt->second, NULL, 0); D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.h b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.h index 688bfcc216..7c696e358b 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.h @@ -38,7 +38,8 @@ public: void Init(); void Shutdown(); // Returns true on success, false on failure - bool SetShader(u32 components, float pointSize, float texOffset); + bool SetShader(u32 components, float pointSize, float texOffset, + float vpWidth, float vpHeight); private: diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index c6fada7d20..2017ce335a 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -155,8 +155,10 @@ void VertexManager::Draw(UINT stride) { float lineWidth = float(bpmem.lineptwidth.linesize) / 6.f; float texOffset = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.lineoff]; + float vpWidth = 2.0f * xfregs.rawViewport[0]; + float vpHeight = -2.0f * xfregs.rawViewport[1]; - if (m_lineShader.SetShader(g_nativeVertexFmt->m_components, lineWidth, texOffset)) + if (m_lineShader.SetShader(g_nativeVertexFmt->m_components, lineWidth, texOffset, vpWidth, vpHeight)) { D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); D3D::context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_lineDrawIndex, 0); @@ -169,8 +171,10 @@ void VertexManager::Draw(UINT stride) { float pointSize = float(bpmem.lineptwidth.pointsize) / 6.f; float texOffset = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.pointoff]; + float vpWidth = 2.0f * xfregs.rawViewport[0]; + float vpHeight = -2.0f * xfregs.rawViewport[1]; - if (m_pointShader.SetShader(g_nativeVertexFmt->m_components, pointSize, texOffset)) + if (m_pointShader.SetShader(g_nativeVertexFmt->m_components, pointSize, texOffset, vpWidth, vpHeight)) { D3D::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); D3D::context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_pointDrawIndex, 0);