Vulkan: Add support for barycentric coordinates

Barycentric coordinates are used for the wireframe shader. It was
already implemented, but was made broken or when we change the depth
range or when we added support for fallback of shader viewport/layer
rendering. The previous implementation didn't use the correct
EmitVertex leading to incorrect depths. Also the shader layouts where
not Vulkan compliant.

![image](/attachments/39fbfd9e-16fd-42d8-9520-3d8fa839e7de)

Pull Request: https://projects.blender.org/blender/blender/pulls/124048
This commit is contained in:
Jeroen Bakker
2024-07-02 15:59:16 +02:00
parent c6bdeebf9a
commit 4394b87012

View File

@@ -868,8 +868,8 @@ std::string VKShader::vertex_interface_declare(const shader::ShaderCreateInfo &i
}
if (bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD)) {
/* Need this for stable barycentric. */
ss << "flat out vec4 gpu_pos_flat;\n";
ss << "out vec4 gpu_pos;\n";
ss << "layout(location=" << (location++) << ") flat out vec4 gpu_pos_flat;\n";
ss << "layout(location=" << (location++) << ") out vec4 gpu_pos;\n";
post_main += " gpu_pos = gpu_pos_flat = gl_Position;\n";
}
@@ -962,6 +962,16 @@ std::string VKShader::fragment_interface_declare(const shader::ShaderCreateInfo
}
if (bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD)) {
/* TODO: add support for
* https://docs.vulkan.org/features/latest/features/proposals/VK_KHR_fragment_shader_barycentric.html
*/
ss << "layout(location=" << (location) << ") flat in vec4 gpu_pos[3];\n";
location += 3;
ss << "layout(location=" << (location++) << ") smooth in vec3 gpu_BaryCoord;\n";
ss << "layout(location=" << (location++) << ") noperspective in vec3 gpu_BaryCoordNoPersp;\n";
ss << "#define gpu_position_at_vertex(v) gpu_pos[v]\n";
#if 0
std::cout << "native" << std::endl;
/* NOTE(fclem): This won't work with geometry shader. Hopefully, we don't need geometry
* shader workaround if this extension/feature is detected. */
@@ -987,6 +997,7 @@ std::string VKShader::fragment_interface_declare(const shader::ShaderCreateInfo
pre_main += " gpu_BaryCoord = stable_bary_(gl_BaryCoordSmoothAMD);\n";
pre_main += " gpu_BaryCoordNoPersp = stable_bary_(gl_BaryCoordNoPerspAMD);\n";
#endif
}
if (info.early_fragment_test_) {
ss << "layout(early_fragment_tests) in;\n";
@@ -1192,9 +1203,10 @@ std::string VKShader::workaround_geometry_shader_source_create(
ss << "layout(location=" << (location++) << ") in int gpu_ViewportIndex[];\n";
}
if (do_barycentric_workaround) {
ss << "flat out vec4 gpu_pos[3];\n";
ss << "smooth out vec3 gpu_BaryCoord;\n";
ss << "noperspective out vec3 gpu_BaryCoordNoPersp;\n";
ss << "layout(location=" << (location) << ") flat out vec4 gpu_pos[3];\n";
location += 3;
ss << "layout(location=" << (location++) << ") smooth out vec3 gpu_BaryCoord;\n";
ss << "layout(location=" << (location++) << ") noperspective out vec3 gpu_BaryCoordNoPersp;\n";
}
ss << "\n";
@@ -1223,7 +1235,7 @@ std::string VKShader::workaround_geometry_shader_source_create(
ss << " vec3(" << int(i == 0) << ", " << int(i == 1) << ", " << int(i == 2) << ");\n";
}
ss << " gl_Position = gl_in[" << i << "].gl_Position;\n";
ss << " EmitVertex();\n";
ss << " gpu_EmitVertex();\n";
}
ss << "}\n";
return ss.str();