summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-05-13 04:32:41 -0300
committerGravatar ReinUsesLisp2020-05-13 04:36:47 -0300
commit91dddca26eca0c2e00bb2974099908bf26d34f43 (patch)
tree534a2fd5bef3b757a78dd99429843f6eadc752e4 /src
parentvk_rasterizer: Remove buffer check in attribute selection (diff)
downloadyuzu-91dddca26eca0c2e00bb2974099908bf26d34f43.tar.gz
yuzu-91dddca26eca0c2e00bb2974099908bf26d34f43.tar.xz
yuzu-91dddca26eca0c2e00bb2974099908bf26d34f43.zip
vk_rasterizer: Implement constant attributes
Constant attributes (in OpenGL known disabled attributes) are not supported on Vulkan, even with extensions. To emulate this behavior we return zero on reads from disabled vertex attributes in shader code. This has no caching cost because attribute formats are not dynamic state on Vulkan and we have to store it in the pipeline cache anyway. - Fixes Animal Crossing: New Horizons terrain borders
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp30
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.h3
4 files changed, 26 insertions, 13 deletions
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index fe45ed269..890175d2d 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -312,7 +312,9 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) {
312 ASSERT(point_size != 0.0f); 312 ASSERT(point_size != 0.0f);
313 } 313 }
314 for (std::size_t i = 0; i < Maxwell::NumVertexAttributes; ++i) { 314 for (std::size_t i = 0; i < Maxwell::NumVertexAttributes; ++i) {
315 specialization.attribute_types[i] = fixed_state.vertex_input.attributes[i].Type(); 315 const auto& attribute = fixed_state.vertex_input.attributes[i];
316 specialization.enabled_attributes[i] = attribute.enabled.Value() != 0;
317 specialization.attribute_types[i] = attribute.Type();
316 } 318 }
317 specialization.ndc_minus_one_to_one = fixed_state.rasterizer.ndc_minus_one_to_one; 319 specialization.ndc_minus_one_to_one = fixed_state.rasterizer.ndc_minus_one_to_one;
318 320
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 5af2a0d25..cf15e6d1c 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -875,7 +875,7 @@ void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex
875 875
876 for (std::size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { 876 for (std::size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
877 const auto& attrib = regs.vertex_attrib_format[index]; 877 const auto& attrib = regs.vertex_attrib_format[index];
878 if (!attrib.IsValid()) { 878 if (attrib.IsConstant()) {
879 vertex_input.SetAttribute(index, false, 0, 0, {}, {}); 879 vertex_input.SetAttribute(index, false, 0, 0, {}, {});
880 continue; 880 continue;
881 } 881 }
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index 18678968c..6ce6bfcb5 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -731,8 +731,10 @@ private:
731 if (!IsGenericAttribute(index)) { 731 if (!IsGenericAttribute(index)) {
732 continue; 732 continue;
733 } 733 }
734
735 const u32 location = GetGenericAttributeLocation(index); 734 const u32 location = GetGenericAttributeLocation(index);
735 if (!IsAttributeEnabled(location)) {
736 continue;
737 }
736 const auto type_descriptor = GetAttributeType(location); 738 const auto type_descriptor = GetAttributeType(location);
737 Id type; 739 Id type;
738 if (IsInputAttributeArray()) { 740 if (IsInputAttributeArray()) {
@@ -976,6 +978,10 @@ private:
976 return stage == ShaderType::TesselationControl; 978 return stage == ShaderType::TesselationControl;
977 } 979 }
978 980
981 bool IsAttributeEnabled(u32 location) const {
982 return stage != ShaderType::Vertex || specialization.enabled_attributes[location];
983 }
984
979 u32 GetNumInputVertices() const { 985 u32 GetNumInputVertices() const {
980 switch (stage) { 986 switch (stage) {
981 case ShaderType::Geometry: 987 case ShaderType::Geometry:
@@ -1192,16 +1198,20 @@ private:
1192 UNIMPLEMENTED_MSG("Unmanaged FrontFacing element={}", element); 1198 UNIMPLEMENTED_MSG("Unmanaged FrontFacing element={}", element);
1193 return {v_float_zero, Type::Float}; 1199 return {v_float_zero, Type::Float};
1194 default: 1200 default:
1195 if (IsGenericAttribute(attribute)) { 1201 if (!IsGenericAttribute(attribute)) {
1196 const u32 location = GetGenericAttributeLocation(attribute); 1202 break;
1197 const auto type_descriptor = GetAttributeType(location);
1198 const Type type = type_descriptor.type;
1199 const Id attribute_id = input_attributes.at(attribute);
1200 const std::vector elements = {element};
1201 const Id pointer = ArrayPass(type_descriptor.scalar, attribute_id, elements);
1202 return {OpLoad(GetTypeDefinition(type), pointer), type};
1203 } 1203 }
1204 break; 1204 const u32 location = GetGenericAttributeLocation(attribute);
1205 if (!IsAttributeEnabled(location)) {
1206 // Disabled attributes (also known as constant attributes) always return zero.
1207 return {v_float_zero, Type::Float};
1208 }
1209 const auto type_descriptor = GetAttributeType(location);
1210 const Type type = type_descriptor.type;
1211 const Id attribute_id = input_attributes.at(attribute);
1212 const std::vector elements = {element};
1213 const Id pointer = ArrayPass(type_descriptor.scalar, attribute_id, elements);
1214 return {OpLoad(GetTypeDefinition(type), pointer), type};
1205 } 1215 }
1206 UNIMPLEMENTED_MSG("Unhandled input attribute: {}", static_cast<u32>(attribute)); 1216 UNIMPLEMENTED_MSG("Unhandled input attribute: {}", static_cast<u32>(attribute));
1207 return {v_float_zero, Type::Float}; 1217 return {v_float_zero, Type::Float};
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.h b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
index f4c05ac3c..b7af26388 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.h
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.h
@@ -88,7 +88,8 @@ struct Specialization final {
88 u32 shared_memory_size{}; 88 u32 shared_memory_size{};
89 89
90 // Graphics specific 90 // Graphics specific
91 std::optional<float> point_size{}; 91 std::optional<float> point_size;
92 std::bitset<Maxwell::NumVertexAttributes> enabled_attributes;
92 std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{}; 93 std::array<Maxwell::VertexAttribute::Type, Maxwell::NumVertexAttributes> attribute_types{};
93 bool ndc_minus_one_to_one{}; 94 bool ndc_minus_one_to_one{};
94}; 95};