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
This commit is contained in:
parent
975ce523b6
commit
40b8db30e3
|
@ -31,6 +31,8 @@ union LineGSParams
|
||||||
{
|
{
|
||||||
FLOAT LineWidth; // In units of 1/6 of an EFB pixel
|
FLOAT LineWidth; // In units of 1/6 of an EFB pixel
|
||||||
FLOAT TexOffset;
|
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.
|
// Constant buffers must be a multiple of 16 bytes in size.
|
||||||
u8 pad[16]; // Pad to the next multiple of 16 bytes
|
u8 pad[16]; // Pad to the next multiple of 16 bytes
|
||||||
|
@ -46,6 +48,8 @@ static const char LINE_GS_COMMON[] =
|
||||||
"{\n"
|
"{\n"
|
||||||
"float LineWidth;\n"
|
"float LineWidth;\n"
|
||||||
"float TexOffset;\n"
|
"float TexOffset;\n"
|
||||||
|
"float VpWidth;\n"
|
||||||
|
"float VpHeight;\n"
|
||||||
"} Params;\n"
|
"} Params;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
|
@ -65,17 +69,17 @@ static const char LINE_GS_COMMON[] =
|
||||||
// horizontal depending the slope of the line.
|
// horizontal depending the slope of the line.
|
||||||
|
|
||||||
"float2 offset;\n"
|
"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: 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.
|
// 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.
|
// Line is more tall. Extend geometry left and right.
|
||||||
// Lerp Params.LineWidth/2 from [0..640] to [-1..1]
|
// Lerp Params.LineWidth/2 from [0..VpWidth] to [-1..1]
|
||||||
"offset = float2(Params.LineWidth/640, 0);\n"
|
"offset = float2(Params.LineWidth/Params.VpWidth, 0);\n"
|
||||||
"} else {\n"
|
"} else {\n"
|
||||||
// Line is more wide. Extend geometry up and down.
|
// Line is more wide. Extend geometry up and down.
|
||||||
// Lerp Params.LineWidth/2 from [0..528] to [1..-1]
|
// Lerp Params.LineWidth/2 from [0..VpHeight] to [1..-1]
|
||||||
"offset = float2(0, -Params.LineWidth/528);\n"
|
"offset = float2(0, -Params.LineWidth/Params.VpHeight);\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
"l0.pos.xy -= offset * input[0].pos.w;\n"
|
"l0.pos.xy -= offset * input[0].pos.w;\n"
|
||||||
|
@ -164,7 +168,8 @@ void LineGeometryShader::Shutdown()
|
||||||
SAFE_RELEASE(m_paramsBuffer);
|
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)
|
if (!m_ready)
|
||||||
return false;
|
return false;
|
||||||
|
@ -208,8 +213,13 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth, float texOff
|
||||||
LineGSParams params = { 0 };
|
LineGSParams params = { 0 };
|
||||||
params.LineWidth = lineWidth;
|
params.LineWidth = lineWidth;
|
||||||
params.TexOffset = texOffset;
|
params.TexOffset = texOffset;
|
||||||
|
params.VpWidth = vpWidth;
|
||||||
|
params.VpHeight = vpHeight;
|
||||||
D3D::context->UpdateSubresource(m_paramsBuffer, 0, NULL, ¶ms, 0, 0);
|
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->GSSetShader(shaderIt->second, NULL, 0);
|
||||||
D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer);
|
D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer);
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,8 @@ public:
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
// Returns true on success, false on failure
|
// 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:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ union PointGSParams
|
||||||
{
|
{
|
||||||
FLOAT PointSize; // In units of 1/6 of an EFB pixel
|
FLOAT PointSize; // In units of 1/6 of an EFB pixel
|
||||||
FLOAT TexOffset;
|
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.
|
// Constant buffers must be a multiple of 16 bytes in size.
|
||||||
u8 pad[16]; // Pad to the next multiple of 16 bytes
|
u8 pad[16]; // Pad to the next multiple of 16 bytes
|
||||||
|
@ -46,6 +48,8 @@ static const char POINT_GS_COMMON[] =
|
||||||
"{\n"
|
"{\n"
|
||||||
"float PointSize;\n"
|
"float PointSize;\n"
|
||||||
"float TexOffset;\n"
|
"float TexOffset;\n"
|
||||||
|
"float VpWidth;\n"
|
||||||
|
"float VpHeight;\n"
|
||||||
"} Params;\n"
|
"} Params;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
|
@ -58,8 +62,8 @@ static const char POINT_GS_COMMON[] =
|
||||||
"VS_OUTPUT ptUR = ptLL;\n"
|
"VS_OUTPUT ptUR = ptLL;\n"
|
||||||
|
|
||||||
// Offset from center to upper right vertex
|
// Offset from center to upper right vertex
|
||||||
// Lerp Params.PointSize/2 from [0,0..640,528] to [-1,1..1,-1]
|
// Lerp Params.PointSize/2 from [0,0..VpWidth,VpHeight] to [-1,1..1,-1]
|
||||||
"float2 offset = float2(Params.PointSize/640, -Params.PointSize/528) * input[0].pos.w;\n"
|
"float2 offset = float2(Params.PointSize/Params.VpWidth, -Params.PointSize/Params.VpHeight) * input[0].pos.w;\n"
|
||||||
|
|
||||||
"ptLL.pos.xy += float2(-1,-1) * offset;\n"
|
"ptLL.pos.xy += float2(-1,-1) * offset;\n"
|
||||||
"ptLR.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);
|
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)
|
if (!m_ready)
|
||||||
return false;
|
return false;
|
||||||
|
@ -201,7 +206,12 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize, float texOf
|
||||||
PointGSParams params = { 0 };
|
PointGSParams params = { 0 };
|
||||||
params.PointSize = pointSize;
|
params.PointSize = pointSize;
|
||||||
params.TexOffset = texOffset;
|
params.TexOffset = texOffset;
|
||||||
|
params.VpWidth = vpWidth;
|
||||||
|
params.VpHeight = vpHeight;
|
||||||
D3D::context->UpdateSubresource(m_paramsBuffer, 0, NULL, ¶ms, 0, 0);
|
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->GSSetShader(shaderIt->second, NULL, 0);
|
||||||
D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer);
|
D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer);
|
||||||
|
|
|
@ -38,7 +38,8 @@ public:
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
// Returns true on success, false on failure
|
// 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:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -155,8 +155,10 @@ void VertexManager::Draw(UINT stride)
|
||||||
{
|
{
|
||||||
float lineWidth = float(bpmem.lineptwidth.linesize) / 6.f;
|
float lineWidth = float(bpmem.lineptwidth.linesize) / 6.f;
|
||||||
float texOffset = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.lineoff];
|
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->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
||||||
D3D::context->DrawIndexed(IndexGenerator::GetLineindexLen(), m_lineDrawIndex, 0);
|
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 pointSize = float(bpmem.lineptwidth.pointsize) / 6.f;
|
||||||
float texOffset = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.pointoff];
|
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->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||||
D3D::context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_pointDrawIndex, 0);
|
D3D::context->DrawIndexed(IndexGenerator::GetPointindexLen(), m_pointDrawIndex, 0);
|
||||||
|
|
Loading…
Reference in New Issue