diff options
| author | JMC47 <JMC4789@gmail.com> | 2022-10-23 01:49:26 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-23 01:49:26 -0400 |
| commit | cdcbe51b2a0c4dd78ab8d1d3ad38d8ab2947405b (patch) | |
| tree | 5d29d92713f591f003b7d83da63b427b3c847ea1 /Source/Core/VideoCommon/VertexShaderGen.cpp | |
| parent | 06bd0a908692f61702a483c51c93fadb2ed7eefc (diff) | |
| parent | 1e9b6f88e4c13722a2a47aeb0d54df95c3a07c69 (diff) | |
Merge pull request #10890 from tellowkrinkle/VertexLineExpand
VideoCommon: Add vertex shader point/line expansion
Diffstat (limited to 'Source/Core/VideoCommon/VertexShaderGen.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/VertexShaderGen.cpp | 192 |
1 files changed, 172 insertions, 20 deletions
diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index 2eb5a53a97..5570e52cc0 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -6,6 +6,7 @@ #include "Common/Assert.h" #include "Common/CommonTypes.h" #include "VideoCommon/BPMemory.h" +#include "VideoCommon/ConstantManager.h" #include "VideoCommon/LightingShaderGen.h" #include "VideoCommon/NativeVertexFormat.h" #include "VideoCommon/VertexLoaderManager.h" @@ -83,6 +84,8 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho const bool ssaa = host_config.ssaa; const bool vertex_rounding = host_config.vertex_rounding; + ShaderCode input_extract; + out.Write("{}", s_lighting_struct); // uniforms @@ -91,6 +94,21 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho out.Write("{}", s_shader_uniforms); out.Write("}};\n"); + if (uid_data->vs_expand != VSExpand::None) + { + out.Write("UBO_BINDING(std140, 3) uniform GSBlock {{\n"); + out.Write("{}", s_geometry_shader_uniforms); + out.Write("}};\n"); + + if (api_type == APIType::D3D) + { + // D3D doesn't include the base vertex in SV_VertexID + out.Write("UBO_BINDING(std140, 4) uniform DX_Constants {{\n" + " uint base_vertex;\n" + "}};\n\n"); + } + } + out.Write("struct VS_OUTPUT {{\n"); GenerateVSOutputMembers(out, api_type, uid_data->numTexGens, host_config, "", ShaderStage::Vertex); @@ -98,30 +116,113 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho WriteIsNanHeader(out, api_type); - out.Write("ATTRIBUTE_LOCATION({}) in float4 rawpos;\n", SHADER_POSITION_ATTRIB); - if ((uid_data->components & VB_HAS_POSMTXIDX) != 0) - out.Write("ATTRIBUTE_LOCATION({}) in uint4 posmtx;\n", SHADER_POSMTX_ATTRIB); - if ((uid_data->components & VB_HAS_NORMAL) != 0) - out.Write("ATTRIBUTE_LOCATION({}) in float3 rawnormal;\n", SHADER_NORMAL_ATTRIB); - if ((uid_data->components & VB_HAS_TANGENT) != 0) - out.Write("ATTRIBUTE_LOCATION({}) in float3 rawtangent;\n", SHADER_TANGENT_ATTRIB); - if ((uid_data->components & VB_HAS_BINORMAL) != 0) - out.Write("ATTRIBUTE_LOCATION({}) in float3 rawbinormal;\n", SHADER_BINORMAL_ATTRIB); - - if ((uid_data->components & VB_HAS_COL0) != 0) - out.Write("ATTRIBUTE_LOCATION({}) in float4 rawcolor0;\n", SHADER_COLOR0_ATTRIB); - if ((uid_data->components & VB_HAS_COL1) != 0) - out.Write("ATTRIBUTE_LOCATION({}) in float4 rawcolor1;\n", SHADER_COLOR1_ATTRIB); - - for (u32 i = 0; i < 8; ++i) + if (uid_data->vs_expand == VSExpand::None) { - const u32 has_texmtx = (uid_data->components & (VB_HAS_TEXMTXIDX0 << i)); + out.Write("ATTRIBUTE_LOCATION({}) in float4 rawpos;\n", SHADER_POSITION_ATTRIB); + if ((uid_data->components & VB_HAS_POSMTXIDX) != 0) + out.Write("ATTRIBUTE_LOCATION({}) in uint4 posmtx;\n", SHADER_POSMTX_ATTRIB); + if ((uid_data->components & VB_HAS_NORMAL) != 0) + out.Write("ATTRIBUTE_LOCATION({}) in float3 rawnormal;\n", SHADER_NORMAL_ATTRIB); + if ((uid_data->components & VB_HAS_TANGENT) != 0) + out.Write("ATTRIBUTE_LOCATION({}) in float3 rawtangent;\n", SHADER_TANGENT_ATTRIB); + if ((uid_data->components & VB_HAS_BINORMAL) != 0) + out.Write("ATTRIBUTE_LOCATION({}) in float3 rawbinormal;\n", SHADER_BINORMAL_ATTRIB); + + if ((uid_data->components & VB_HAS_COL0) != 0) + out.Write("ATTRIBUTE_LOCATION({}) in float4 rawcolor0;\n", SHADER_COLOR0_ATTRIB); + if ((uid_data->components & VB_HAS_COL1) != 0) + out.Write("ATTRIBUTE_LOCATION({}) in float4 rawcolor1;\n", SHADER_COLOR1_ATTRIB); + + for (u32 i = 0; i < 8; ++i) + { + const u32 has_texmtx = (uid_data->components & (VB_HAS_TEXMTXIDX0 << i)); - if ((uid_data->components & (VB_HAS_UV0 << i)) != 0 || has_texmtx != 0) + if ((uid_data->components & (VB_HAS_UV0 << i)) != 0 || has_texmtx != 0) + { + out.Write("ATTRIBUTE_LOCATION({}) in float{} rawtex{};\n", SHADER_TEXTURE0_ATTRIB + i, + has_texmtx != 0 ? 3 : 2, i); + } + } + } + else + { + // Can't use float3, etc because we want 4-byte alignment + out.Write( + "uint4 unpack_ubyte4(uint value) {{\n" + " return uint4(value & 0xff, (value >> 8) & 0xff, (value >> 16) & 0xff, value >> 24);\n" + "}}\n\n" + "struct InputData {{\n"); + if (uid_data->components & VB_HAS_POSMTXIDX) + { + out.Write(" uint posmtx;\n"); + input_extract.Write("uint4 posmtx = unpack_ubyte4(i.posmtx);\n"); + } + if (uid_data->position_has_3_elems) + { + out.Write(" float pos0;\n" + " float pos1;\n" + " float pos2;\n"); + input_extract.Write("float4 rawpos = float4(i.pos0, i.pos1, i.pos2, 1.0f);\n"); + } + else + { + out.Write(" float pos0;\n" + " float pos1;\n"); + input_extract.Write("float4 rawpos = float4(i.pos0, i.pos1, 0.0f, 1.0f);\n"); + } + std::array<std::string_view, 3> names = {"normal", "binormal", "tangent"}; + for (int i = 0; i < 3; i++) + { + if (uid_data->components & (VB_HAS_NORMAL << i)) + { + out.Write(" float {0}0;\n" + " float {0}1;\n" + " float {0}2;\n", + names[i]); + input_extract.Write("float3 raw{0} = float3(i.{0}0, i.{0}1, i.{0}2);\n", names[i]); + } + } + for (int i = 0; i < 2; i++) + { + if (uid_data->components & (VB_HAS_COL0 << i)) + { + out.Write(" uint color{};\n", i); + input_extract.Write("float4 rawcolor{0} = float4(unpack_ubyte4(i.color{0})) / 255.0f;\n", + i); + } + } + for (int i = 0; i < 8; i++) { - out.Write("ATTRIBUTE_LOCATION({}) in float{} rawtex{};\n", SHADER_TEXTURE0_ATTRIB + i, - has_texmtx != 0 ? 3 : 2, i); + if (uid_data->components & (VB_HAS_UV0 << i)) + { + u32 ncomponents = (uid_data->texcoord_elem_count >> (2 * i)) & 3; + if (ncomponents < 2) + { + out.Write(" float tex{};\n", i); + input_extract.Write("float3 rawtex{0} = float3(i.tex{0}, 0.0f, 0.0f);\n", i); + } + else if (ncomponents == 2) + { + out.Write(" float tex{0}_0;\n" + " float tex{0}_1;\n", + i); + input_extract.Write("float3 rawtex{0} = float3(i.tex{0}_0, i.tex{0}_1, 0.0f);\n", i); + } + else + { + out.Write(" float tex{0}_0;\n" + " float tex{0}_1;\n" + " float tex{0}_2;\n", + i); + input_extract.Write("float3 rawtex{0} = float3(i.tex{0}_0, i.tex{0}_1, i.tex{0}_2);\n", + i); + } + } } + out.Write("}};\n\n" + "SSBO_BINDING(1) readonly restrict buffer InputBuffer {{\n" + " InputData input_buffer[];\n" + "}};\n\n"); } if (host_config.backend_geometry_shaders) @@ -161,6 +262,21 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho out.Write("void main()\n{{\n"); + if (uid_data->vs_expand != VSExpand::None) + { + out.Write("bool is_bottom = (gl_VertexID & 2) != 0;\n" + "bool is_right = (gl_VertexID & 1) != 0;\n"); + // D3D doesn't include the base vertex in SV_VertexID + // See comment in UberShaderVertex for details + if (api_type == APIType::D3D) + out.Write("uint vertex_id = (gl_VertexID >> 2) + base_vertex;\n"); + else + out.Write("uint vertex_id = gl_VertexID >> 2;\n"); + out.Write("InputData i = input_buffer[vertex_id];\n" + "{}", + input_extract.GetBuffer()); + } + out.Write("VS_OUTPUT o;\n"); // xfmem.numColorChans controls the number of color channels available to TEV, but we still need @@ -403,6 +519,42 @@ ShaderCode GenerateVertexShaderCode(APIType api_type, const ShaderHostConfig& ho out.Write("}}\n"); } + if (uid_data->vs_expand == VSExpand::Line) + { + out.Write("// Line expansion\n" + "uint other_id = vertex_id;\n" + "if (is_bottom) {{\n" + " other_id -= 1;\n" + "}} else {{\n" + " other_id += 1;\n" + "}}\n" + "InputData other = input_buffer[other_id];\n"); + if (uid_data->position_has_3_elems) + out.Write("float4 other_pos = float4(other.pos0, other.pos1, other.pos2, 1.0f);\n"); + else + out.Write("float4 other_pos = float4(other.pos0, other.pos1, 0.0f, 1.0f);\n"); + if (uid_data->components & VB_HAS_POSMTXIDX) + { + out.Write("uint other_posidx = other.posmtx & 0xff;\n" + "float4 other_p0 = " I_TRANSFORMMATRICES "[other_posidx];\n" + "float4 other_p1 = " I_TRANSFORMMATRICES "[other_posidx + 1];\n" + "float4 other_p2 = " I_TRANSFORMMATRICES "[other_posidx + 2];\n" + "other_pos = float4(dot(other_p0, other_pos), dot(other_p1, other_pos), " + "dot(other_p2, other_pos), 1.0f);\n"); + } + else + { + out.Write("other_pos = float4(dot(P0, other_pos), dot(P1, other_pos), dot(P2, other_pos), " + "1.0f);\n"); + } + GenerateVSLineExpansion(out, "", uid_data->numTexGens); + } + else if (uid_data->vs_expand == VSExpand::Point) + { + out.Write("// Point expansion\n"); + GenerateVSPointExpansion(out, "", uid_data->numTexGens); + } + if (per_pixel_lighting) { // When per-pixel lighting is enabled, the vertex colors are passed through |
