fix(agc): do not use fragment barycentric on MoltenVK
MoltenVK reports VK_KHR_fragment_shader_barycentric, but its SPIR-V to MSL step rejects the PerVertexKHR decoration that the barycentric path uses, so every pixel shader on that path fails to compile into a pipeline. Treat the feature as unavailable when the driver is MoltenVK, so the no-barycentric path is used. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
4b005b229e
commit
5333a20537
|
|
@ -284,6 +284,15 @@ target_link_libraries(agc_structurizer_tests PRIVATE shader_recompiler_agc_drive
|
|||
set_target_properties(agc_structurizer_tests PROPERTIES CXX_EXTENSIONS OFF)
|
||||
configure_windows_unwind(agc_structurizer_tests)
|
||||
|
||||
add_test_executable(agc_fragment_barycentric_tests EXCLUDE_FROM_ALL tests/FragmentBarycentric.cpp)
|
||||
target_include_directories(agc_fragment_barycentric_tests PRIVATE ${LIBS_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/3rdparty/Vulkan-Headers/include)
|
||||
set_target_properties(agc_fragment_barycentric_tests PROPERTIES CXX_EXTENSIONS OFF)
|
||||
configure_windows_unwind(agc_fragment_barycentric_tests)
|
||||
if(BUILD_TESTING)
|
||||
set_target_properties(agc_fragment_barycentric_tests PROPERTIES EXCLUDE_FROM_ALL OFF)
|
||||
add_test(NAME agc_fragment_barycentric COMMAND agc_fragment_barycentric_tests)
|
||||
endif()
|
||||
|
||||
add_test_executable(agc_subgroup_clock_tests EXCLUDE_FROM_ALL
|
||||
tests/SubgroupClock.cpp
|
||||
Execution/src/SubgroupClock.cpp
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_FRAGMENTBARYCENTRIC_HPP
|
||||
#define CORE_LIBS_PRX_LIBSCEAGCDRIVER_EXECUTION_INCLUDE_FRAGMENTBARYCENTRIC_HPP
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
namespace AgcDriver {
|
||||
|
||||
inline bool FragmentShaderBarycentricUsable(VkDriverId driver, bool reported) {
|
||||
return reported && driver != VK_DRIVER_ID_MOLTENVK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
#include "prx/libSceAgcDriver/Execution/include/Driver.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/PerformanceTimer.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/BdaFeatures.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/FragmentBarycentric.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/SubgroupClock.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/PresentationScaler.hpp"
|
||||
#include "prx/libSceAgcDriver/Graphics/include/DepthSurface.hpp"
|
||||
|
|
@ -756,6 +757,12 @@ VulkanDevice::VulkanDevice(const PresentationWindow* window) : state(std::make_u
|
|||
VkPhysicalDeviceFeatures2 features{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, &barycentricFeatures};
|
||||
state->InstanceFunction<PFN_vkGetPhysicalDeviceFeatures2>("vkGetPhysicalDeviceFeatures2")(selected, &features);
|
||||
state->fragmentShaderBarycentric = barycentricFeatures.fragmentShaderBarycentric == VK_TRUE;
|
||||
if (state->fragmentShaderBarycentric && hasExtension(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) {
|
||||
VkPhysicalDeviceDriverProperties driver{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES};
|
||||
VkPhysicalDeviceProperties2 driverProperties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, &driver};
|
||||
state->InstanceFunction<PFN_vkGetPhysicalDeviceProperties2>("vkGetPhysicalDeviceProperties2")(selected, &driverProperties);
|
||||
state->fragmentShaderBarycentric = FragmentShaderBarycentricUsable(driver.driverID, state->fragmentShaderBarycentric);
|
||||
}
|
||||
}
|
||||
VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT interlockFeatures{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT};
|
||||
if (hasExtension(VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
#include "prx/libSceAgcDriver/Execution/include/FragmentBarycentric.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
namespace {
|
||||
|
||||
struct Case {
|
||||
VkDriverId driver;
|
||||
bool reported;
|
||||
bool usable;
|
||||
};
|
||||
|
||||
constexpr Case Cases[]{
|
||||
{VK_DRIVER_ID_MOLTENVK, true, false},
|
||||
{VK_DRIVER_ID_MOLTENVK, false, false},
|
||||
{VK_DRIVER_ID_MESA_RADV, true, true},
|
||||
{VK_DRIVER_ID_MESA_RADV, false, false},
|
||||
{VK_DRIVER_ID_NVIDIA_PROPRIETARY, true, true},
|
||||
{VK_DRIVER_ID_AMD_PROPRIETARY, true, true},
|
||||
{VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS, false, false},
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
int failures = 0;
|
||||
for (const auto& item : Cases) {
|
||||
if (AgcDriver::FragmentShaderBarycentricUsable(item.driver, item.reported) != item.usable) {
|
||||
std::fprintf(stderr, "driver %d reported %d: expected %s fragment barycentric\n", static_cast<int>(item.driver), item.reported ? 1 : 0, item.usable ? "usable" : "unusable");
|
||||
++failures;
|
||||
}
|
||||
}
|
||||
return failures == 0 ? 0 : 1;
|
||||
}
|
||||
Loading…
Reference in New Issue