mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 16:19:28 +01:00
VideoCommon: Move repeated point/line expansion code to ShaderGenCommon
This commit is contained in:
parent
0a42c534c3
commit
b567f3afcf
@ -169,22 +169,7 @@ ShaderCode GenerateGeometryShaderCode(APIType api_type, const ShaderHostConfig&
|
|||||||
"\tVS_OUTPUT end = o[1];\n");
|
"\tVS_OUTPUT end = o[1];\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// GameCube/Wii's line drawing algorithm is a little quirky. It does not
|
GenerateLineOffset(out, "\t", "\t\t", "end.pos", "start.pos", "");
|
||||||
// use the correct line caps. Instead, the line caps are vertical or
|
|
||||||
// horizontal depending the slope of the line.
|
|
||||||
out.Write("\tfloat2 offset;\n"
|
|
||||||
"\tfloat2 to = abs(end.pos.xy / end.pos.w - start.pos.xy / start.pos.w);\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.
|
|
||||||
"\tif (" I_LINEPTPARAMS ".y * to.y > " I_LINEPTPARAMS ".x * to.x) {{\n"
|
|
||||||
// Line is more tall. Extend geometry left and right.
|
|
||||||
// Lerp LineWidth/2 from [0..VpWidth] to [-1..1]
|
|
||||||
"\t\toffset = float2(" I_LINEPTPARAMS ".z / " I_LINEPTPARAMS ".x, 0);\n"
|
|
||||||
"\t}} else {{\n"
|
|
||||||
// Line is more wide. Extend geometry up and down.
|
|
||||||
// Lerp LineWidth/2 from [0..VpHeight] to [1..-1]
|
|
||||||
"\t\toffset = float2(0, -" I_LINEPTPARAMS ".z / " I_LINEPTPARAMS ".y);\n"
|
|
||||||
"\t}}\n");
|
|
||||||
}
|
}
|
||||||
else if (primitive_type == PrimitiveType::Points)
|
else if (primitive_type == PrimitiveType::Points)
|
||||||
{
|
{
|
||||||
|
@ -254,6 +254,78 @@ void AssignVSOutputMembers(ShaderCode& object, std::string_view a, std::string_v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GenerateLineOffset(ShaderCode& object, std::string_view indent0, std::string_view indent1,
|
||||||
|
std::string_view pos_a, std::string_view pos_b, std::string_view sign)
|
||||||
|
{
|
||||||
|
// GameCube/Wii's line drawing algorithm is a little quirky. It does not
|
||||||
|
// use the correct line caps. Instead, the line caps are vertical or
|
||||||
|
// horizontal depending the slope of the line.
|
||||||
|
object.Write("{indent0}float2 offset;\n"
|
||||||
|
"{indent0}float2 to = abs({pos_a}.xy / {pos_a}.w - {pos_b}.xy / {pos_b}.w);\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.
|
||||||
|
"{indent0}if (" I_LINEPTPARAMS ".y * to.y > " I_LINEPTPARAMS ".x * to.x) {{\n"
|
||||||
|
// Line is more tall. Extend geometry left and right.
|
||||||
|
// Lerp LineWidth/2 from [0..VpWidth] to [-1..1]
|
||||||
|
"{indent1}offset = float2({sign}" I_LINEPTPARAMS ".z / " I_LINEPTPARAMS ".x, 0);\n"
|
||||||
|
"{indent0}}} else {{\n"
|
||||||
|
// Line is more wide. Extend geometry up and down.
|
||||||
|
// Lerp LineWidth/2 from [0..VpHeight] to [1..-1]
|
||||||
|
"{indent1}offset = float2(0, {sign}-" I_LINEPTPARAMS ".z / " I_LINEPTPARAMS ".y);\n"
|
||||||
|
"{indent0}}}\n",
|
||||||
|
fmt::arg("indent0", indent0), fmt::arg("indent1", indent1), //
|
||||||
|
fmt::arg("pos_a", pos_a), fmt::arg("pos_b", pos_b), fmt::arg("sign", sign));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateVSLineExpansion(ShaderCode& object, std::string_view indent, u32 texgens)
|
||||||
|
{
|
||||||
|
std::string indent1 = std::string(indent) + " ";
|
||||||
|
object.Write("{0}other_pos = float4(dot(" I_PROJECTION "[0], other_pos), dot(" I_PROJECTION
|
||||||
|
"[1], other_pos), dot(" I_PROJECTION "[2], other_pos), dot(" I_PROJECTION
|
||||||
|
"[3], other_pos));\n"
|
||||||
|
"\n"
|
||||||
|
"{0}float expand_sign = is_right ? 1.0f : -1.0f;\n",
|
||||||
|
indent);
|
||||||
|
GenerateLineOffset(object, indent, indent1, "o.pos", "other_pos", "expand_sign * ");
|
||||||
|
object.Write("\n"
|
||||||
|
"{}o.pos.xy += offset * o.pos.w;\n",
|
||||||
|
indent);
|
||||||
|
if (texgens > 0)
|
||||||
|
{
|
||||||
|
object.Write("{}if ((" I_TEXOFFSET "[2] != 0) && is_right) {{\n", indent);
|
||||||
|
object.Write("{} float texOffset = 1.0 / float(" I_TEXOFFSET "[2]);\n", indent);
|
||||||
|
for (u32 i = 0; i < texgens; i++)
|
||||||
|
{
|
||||||
|
object.Write("{} if (((" I_TEXOFFSET "[0] >> {}) & 0x1) != 0)\n", indent, i);
|
||||||
|
object.Write("{} o.tex{}.x += texOffset;\n", indent, i);
|
||||||
|
}
|
||||||
|
object.Write("{}}}\n", indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateVSPointExpansion(ShaderCode& object, std::string_view indent, u32 texgens)
|
||||||
|
{
|
||||||
|
object.Write(
|
||||||
|
"{0}float2 expand_sign = float2(is_right ? 1.0f : -1.0f, is_bottom ? -1.0f : 1.0f);\n"
|
||||||
|
"{0}float2 offset = expand_sign * " I_LINEPTPARAMS ".ww / " I_LINEPTPARAMS ".xy;\n"
|
||||||
|
"{0}o.pos.xy += offset * o.pos.w;\n",
|
||||||
|
indent);
|
||||||
|
if (texgens > 0)
|
||||||
|
{
|
||||||
|
object.Write("{0}if (" I_TEXOFFSET "[3] != 0) {{\n"
|
||||||
|
"{0} float texOffsetMagnitude = 1.0f / float(" I_TEXOFFSET "[3]);\n"
|
||||||
|
"{0} float2 texOffset = float2(is_right ? texOffsetMagnitude : 0.0f, "
|
||||||
|
"is_bottom ? texOffsetMagnitude : 0.0f);",
|
||||||
|
indent);
|
||||||
|
for (u32 i = 0; i < texgens; i++)
|
||||||
|
{
|
||||||
|
object.Write("{} if (((" I_TEXOFFSET "[1] >> {}) & 0x1) != 0)\n", indent, i);
|
||||||
|
object.Write("{} o.tex{}.xy += texOffset;\n", indent, i);
|
||||||
|
}
|
||||||
|
object.Write("{}}}\n", indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char* GetInterpolationQualifier(bool msaa, bool ssaa, bool in_glsl_interface_block, bool in)
|
const char* GetInterpolationQualifier(bool msaa, bool ssaa, bool in_glsl_interface_block, bool in)
|
||||||
{
|
{
|
||||||
if (!msaa)
|
if (!msaa)
|
||||||
|
@ -198,6 +198,13 @@ void GenerateVSOutputMembers(ShaderCode& object, APIType api_type, u32 texgens,
|
|||||||
void AssignVSOutputMembers(ShaderCode& object, std::string_view a, std::string_view b, u32 texgens,
|
void AssignVSOutputMembers(ShaderCode& object, std::string_view a, std::string_view b, u32 texgens,
|
||||||
const ShaderHostConfig& host_config);
|
const ShaderHostConfig& host_config);
|
||||||
|
|
||||||
|
void GenerateLineOffset(ShaderCode& object, std::string_view indent0, std::string_view indent1,
|
||||||
|
std::string_view pos_a, std::string_view pos_b, std::string_view sign);
|
||||||
|
|
||||||
|
void GenerateVSLineExpansion(ShaderCode& object, std::string_view indent, u32 texgens);
|
||||||
|
|
||||||
|
void GenerateVSPointExpansion(ShaderCode& object, std::string_view indent, u32 texgens);
|
||||||
|
|
||||||
// We use the flag "centroid" to fix some MSAA rendering bugs. With MSAA, the
|
// We use the flag "centroid" to fix some MSAA rendering bugs. With MSAA, the
|
||||||
// pixel shader will be executed for each pixel which has at least one passed sample.
|
// pixel shader will be executed for each pixel which has at least one passed sample.
|
||||||
// So there may be rendered pixels where the center of the pixel isn't in the primitive.
|
// So there may be rendered pixels where the center of the pixel isn't in the primitive.
|
||||||
|
@ -356,67 +356,19 @@ float3 load_input_float3_rawtex(uint vtx_offset, uint attr_offset) {{
|
|||||||
" float4 other_p2 = P2;\n"
|
" float4 other_p2 = P2;\n"
|
||||||
" if ((components & {}u) != 0u) {{ // VB_HAS_POSMTXIDX\n",
|
" if ((components & {}u) != 0u) {{ // VB_HAS_POSMTXIDX\n",
|
||||||
VB_HAS_POSMTXIDX);
|
VB_HAS_POSMTXIDX);
|
||||||
out.Write(" uint other_posidx = int(load_input_uint4_ubyte4(other_base_offset, "
|
out.Write(" uint other_posidx = load_input_uint4_ubyte4(other_base_offset, "
|
||||||
"vertex_offset_posmtx).r);\n"
|
"vertex_offset_posmtx).r;\n"
|
||||||
" other_p0 = " I_TRANSFORMMATRICES "[other_posidx];\n"
|
" other_p0 = " I_TRANSFORMMATRICES "[other_posidx];\n"
|
||||||
" other_p1 = " I_TRANSFORMMATRICES "[other_posidx+1];\n"
|
" other_p1 = " I_TRANSFORMMATRICES "[other_posidx+1];\n"
|
||||||
" other_p2 = " I_TRANSFORMMATRICES "[other_posidx+2];\n"
|
" other_p2 = " I_TRANSFORMMATRICES "[other_posidx+2];\n"
|
||||||
" }}\n"
|
" }}\n"
|
||||||
" float4 other_pos = float4(dot(other_p0, other_rawpos), "
|
" float4 other_pos = float4(dot(other_p0, other_rawpos), "
|
||||||
"dot(other_p1, other_rawpos), dot(other_p2, other_rawpos), 1.0);\n"
|
"dot(other_p1, other_rawpos), dot(other_p2, other_rawpos), 1.0);\n");
|
||||||
" other_pos = float4(dot(" I_PROJECTION "[0], other_pos), dot(" I_PROJECTION
|
GenerateVSLineExpansion(out, " ", num_texgen);
|
||||||
"[1], other_pos), dot(" I_PROJECTION "[2], other_pos), dot(" I_PROJECTION
|
|
||||||
"[3], other_pos));\n"
|
|
||||||
"\n"
|
|
||||||
" float sign = is_right ? 1.0f : -1.0f;\n"
|
|
||||||
// GameCube/Wii's line drawing algorithm is a little quirky. It does not
|
|
||||||
// use the correct line caps. Instead, the line caps are vertical or
|
|
||||||
// horizontal depending the slope of the line.
|
|
||||||
" float2 offset;\n"
|
|
||||||
" float2 to = abs(o.pos.xy / o.pos.w - other_pos.xy / other_pos.w);\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 (" I_LINEPTPARAMS ".y * to.y > " I_LINEPTPARAMS ".x * to.x) {{\n"
|
|
||||||
// Line is more tall. Extend geometry left and right.
|
|
||||||
// Lerp LineWidth/2 from [0..VpWidth] to [-1..1]
|
|
||||||
" offset = float2(sign * " I_LINEPTPARAMS ".z / " I_LINEPTPARAMS ".x, 0);\n"
|
|
||||||
" }} else {{\n"
|
|
||||||
// Line is more wide. Extend geometry up and down.
|
|
||||||
// Lerp LineWidth/2 from [0..VpHeight] to [1..-1]
|
|
||||||
" offset = float2(0, sign * " I_LINEPTPARAMS ".z / " I_LINEPTPARAMS ".y);\n"
|
|
||||||
" }}\n"
|
|
||||||
"\n"
|
|
||||||
" o.pos.xy += offset * o.pos.w;\n");
|
|
||||||
if (num_texgen > 0)
|
|
||||||
{
|
|
||||||
out.Write(" if ((" I_TEXOFFSET "[2] != 0) && is_right) {{\n"
|
|
||||||
" float texOffset = 1.0 / float(" I_TEXOFFSET "[2]);\n");
|
|
||||||
for (u32 i = 0; i < num_texgen; i++)
|
|
||||||
{
|
|
||||||
out.Write(" if (((" I_TEXOFFSET "[0] >> {}) & 0x1) != 0)\n", i);
|
|
||||||
out.Write(" o.tex{}.x += texOffset;\n", i);
|
|
||||||
}
|
|
||||||
out.Write(" }}\n");
|
|
||||||
}
|
|
||||||
out.Write("}} else if (vs_expand == {}u) {{ // Point\n", static_cast<u32>(VSExpand::Point));
|
out.Write("}} else if (vs_expand == {}u) {{ // Point\n", static_cast<u32>(VSExpand::Point));
|
||||||
out.Write(" bool is_bottom = (gl_VertexID & 2) != 0;\n"
|
out.Write(" bool is_bottom = (gl_VertexID & 2) != 0;\n"
|
||||||
" bool is_right = (gl_VertexID & 1) != 0;\n"
|
" bool is_right = (gl_VertexID & 1) != 0;\n");
|
||||||
" float2 sign = float2(is_right ? 1.0f : -1.0f, is_bottom ? 1.0f : -1.0f);\n"
|
GenerateVSPointExpansion(out, " ", num_texgen);
|
||||||
" float2 offset = sign * " I_LINEPTPARAMS ".ww / " I_LINEPTPARAMS ".xy;\n"
|
|
||||||
" o.pos.xy += offset * o.pos.w;\n");
|
|
||||||
if (num_texgen > 0)
|
|
||||||
{
|
|
||||||
out.Write(" if (" I_TEXOFFSET "[3] != 0) {{\n"
|
|
||||||
" float texOffsetMagnitude = 1.0f / float(" I_TEXOFFSET "[3]);\n"
|
|
||||||
" float2 texOffset = float2(is_right ? texOffsetMagnitude : 0.0f, "
|
|
||||||
"is_bottom ? texOffsetMagnitude : 0.0f);");
|
|
||||||
for (u32 i = 0; i < num_texgen; i++)
|
|
||||||
{
|
|
||||||
out.Write(" if (((" I_TEXOFFSET "[1] >> {}) & 0x1) != 0)\n", i);
|
|
||||||
out.Write(" o.tex{}.xy += texOffset;\n", i);
|
|
||||||
}
|
|
||||||
out.Write(" }}\n");
|
|
||||||
}
|
|
||||||
out.Write("}}\n");
|
out.Write("}}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,56 +547,12 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho
|
|||||||
out.Write("other_pos = float4(dot(P0, other_pos), dot(P1, other_pos), dot(P2, other_pos), "
|
out.Write("other_pos = float4(dot(P0, other_pos), dot(P1, other_pos), dot(P2, other_pos), "
|
||||||
"1.0f);\n");
|
"1.0f);\n");
|
||||||
}
|
}
|
||||||
out.Write("other_pos = float4(dot(" I_PROJECTION "[0], other_pos), dot(" I_PROJECTION
|
GenerateVSLineExpansion(out, "", uid_data->numTexGens);
|
||||||
"[1], other_pos), dot(" I_PROJECTION "[2], other_pos), dot(" I_PROJECTION
|
|
||||||
"[3], other_pos));\n"
|
|
||||||
"float expand_sign = is_right ? 1.0f : -1.0f;\n"
|
|
||||||
"float2 offset;\n"
|
|
||||||
"float2 to = abs(o.pos.xy / o.pos.w - other_pos.xy / other_pos.w);\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 (" I_LINEPTPARAMS ".y * to.y > " I_LINEPTPARAMS ".x * to.x) {{\n"
|
|
||||||
// Line is more tall. Extend geometry left and right.
|
|
||||||
// Lerp LineWidth/2 from [0..VpWidth] to [-1..1]
|
|
||||||
" offset = float2(expand_sign * " I_LINEPTPARAMS ".z / " I_LINEPTPARAMS ".x, 0);\n"
|
|
||||||
"}} else {{\n"
|
|
||||||
// Line is more wide. Extend geometry up and down.
|
|
||||||
// Lerp LineWidth/2 from [0..VpHeight] to [1..-1]
|
|
||||||
" offset = float2(0, expand_sign * " I_LINEPTPARAMS ".z / " I_LINEPTPARAMS ".y);\n"
|
|
||||||
"}}\n"
|
|
||||||
"\n"
|
|
||||||
"o.pos.xy += offset * o.pos.w;\n");
|
|
||||||
if (uid_data->numTexGens > 0)
|
|
||||||
{
|
|
||||||
out.Write("if ((" I_TEXOFFSET "[2] != 0) && is_right) {{\n"
|
|
||||||
" float texOffset = 1.0 / float(" I_TEXOFFSET "[2]);\n");
|
|
||||||
for (u32 i = 0; i < uid_data->numTexGens; i++)
|
|
||||||
{
|
|
||||||
out.Write(" if (((" I_TEXOFFSET "[0] >> {}) & 0x1) != 0)\n", i);
|
|
||||||
out.Write(" o.tex{}.x += texOffset;\n", i);
|
|
||||||
}
|
|
||||||
out.Write("}}\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (uid_data->vs_expand == VSExpand::Point)
|
else if (uid_data->vs_expand == VSExpand::Point)
|
||||||
{
|
{
|
||||||
out.Write("// Point expansion\n"
|
out.Write("// Point expansion\n");
|
||||||
"float2 expand_sign = float2(is_right ? 1.0f : -1.0f, is_bottom ? 1.0f : -1.0f);\n"
|
GenerateVSPointExpansion(out, "", uid_data->numTexGens);
|
||||||
"float2 offset = expand_sign * " I_LINEPTPARAMS ".ww / " I_LINEPTPARAMS ".xy;\n"
|
|
||||||
"o.pos.xy += offset * o.pos.w;\n");
|
|
||||||
if (uid_data->numTexGens > 0)
|
|
||||||
{
|
|
||||||
out.Write("if (" I_TEXOFFSET "[3] != 0) {{\n"
|
|
||||||
" float texOffsetMagnitude = 1.0f / float(" I_TEXOFFSET "[3]);\n"
|
|
||||||
" float2 texOffset = float2(is_right ? texOffsetMagnitude : 0.0f, "
|
|
||||||
"is_bottom ? texOffsetMagnitude : 0.0f);");
|
|
||||||
for (u32 i = 0; i < uid_data->numTexGens; i++)
|
|
||||||
{
|
|
||||||
out.Write(" if (((" I_TEXOFFSET "[1] >> {}) & 0x1) != 0)\n", i);
|
|
||||||
out.Write(" o.tex{}.xy += texOffset;\n", i);
|
|
||||||
}
|
|
||||||
out.Write("}}\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (per_pixel_lighting)
|
if (per_pixel_lighting)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user