diff options
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_device.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_device.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 105 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_disk_cache.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 16 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 15 |
10 files changed, 137 insertions, 40 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 4aaad2979..79d469b88 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -78,7 +78,7 @@ union Attribute { | |||
| 78 | constexpr explicit Attribute(u64 value) : value(value) {} | 78 | constexpr explicit Attribute(u64 value) : value(value) {} |
| 79 | 79 | ||
| 80 | enum class Index : u64 { | 80 | enum class Index : u64 { |
| 81 | PointSize = 6, | 81 | LayerViewportPointSize = 6, |
| 82 | Position = 7, | 82 | Position = 7, |
| 83 | Attribute_0 = 8, | 83 | Attribute_0 = 8, |
| 84 | Attribute_31 = 39, | 84 | Attribute_31 = 39, |
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index 6238ddaaa..85424a4c9 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp | |||
| @@ -27,6 +27,7 @@ Device::Device() { | |||
| 27 | shader_storage_alignment = GetInteger<std::size_t>(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT); | 27 | shader_storage_alignment = GetInteger<std::size_t>(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT); |
| 28 | max_vertex_attributes = GetInteger<u32>(GL_MAX_VERTEX_ATTRIBS); | 28 | max_vertex_attributes = GetInteger<u32>(GL_MAX_VERTEX_ATTRIBS); |
| 29 | max_varyings = GetInteger<u32>(GL_MAX_VARYING_VECTORS); | 29 | max_varyings = GetInteger<u32>(GL_MAX_VARYING_VECTORS); |
| 30 | has_vertex_viewport_layer = GLAD_GL_ARB_shader_viewport_layer_array; | ||
| 30 | has_variable_aoffi = TestVariableAoffi(); | 31 | has_variable_aoffi = TestVariableAoffi(); |
| 31 | has_component_indexing_bug = TestComponentIndexingBug(); | 32 | has_component_indexing_bug = TestComponentIndexingBug(); |
| 32 | } | 33 | } |
| @@ -35,6 +36,7 @@ Device::Device(std::nullptr_t) { | |||
| 35 | uniform_buffer_alignment = 0; | 36 | uniform_buffer_alignment = 0; |
| 36 | max_vertex_attributes = 16; | 37 | max_vertex_attributes = 16; |
| 37 | max_varyings = 15; | 38 | max_varyings = 15; |
| 39 | has_vertex_viewport_layer = true; | ||
| 38 | has_variable_aoffi = true; | 40 | has_variable_aoffi = true; |
| 39 | has_component_indexing_bug = false; | 41 | has_component_indexing_bug = false; |
| 40 | } | 42 | } |
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h index 939edb440..dc883722d 100644 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h | |||
| @@ -30,6 +30,10 @@ public: | |||
| 30 | return max_varyings; | 30 | return max_varyings; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | bool HasVertexViewportLayer() const { | ||
| 34 | return has_vertex_viewport_layer; | ||
| 35 | } | ||
| 36 | |||
| 33 | bool HasVariableAoffi() const { | 37 | bool HasVariableAoffi() const { |
| 34 | return has_variable_aoffi; | 38 | return has_variable_aoffi; |
| 35 | } | 39 | } |
| @@ -46,6 +50,7 @@ private: | |||
| 46 | std::size_t shader_storage_alignment{}; | 50 | std::size_t shader_storage_alignment{}; |
| 47 | u32 max_vertex_attributes{}; | 51 | u32 max_vertex_attributes{}; |
| 48 | u32 max_varyings{}; | 52 | u32 max_varyings{}; |
| 53 | bool has_vertex_viewport_layer{}; | ||
| 49 | bool has_variable_aoffi{}; | 54 | bool has_variable_aoffi{}; |
| 50 | bool has_component_indexing_bug{}; | 55 | bool has_component_indexing_bug{}; |
| 51 | }; | 56 | }; |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 5d76ee12d..32dd9eae7 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -190,8 +190,11 @@ CachedProgram SpecializeShader(const std::string& code, const GLShader::ShaderEn | |||
| 190 | const auto texture_buffer_usage{variant.texture_buffer_usage}; | 190 | const auto texture_buffer_usage{variant.texture_buffer_usage}; |
| 191 | 191 | ||
| 192 | std::string source = "#version 430 core\n" | 192 | std::string source = "#version 430 core\n" |
| 193 | "#extension GL_ARB_separate_shader_objects : enable\n\n"; | 193 | "#extension GL_ARB_separate_shader_objects : enable\n"; |
| 194 | source += fmt::format("#define EMULATION_UBO_BINDING {}\n", base_bindings.cbuf++); | 194 | if (entries.shader_viewport_layer_array) { |
| 195 | source += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; | ||
| 196 | } | ||
| 197 | source += fmt::format("\n#define EMULATION_UBO_BINDING {}\n", base_bindings.cbuf++); | ||
| 195 | 198 | ||
| 196 | for (const auto& cbuf : entries.const_buffers) { | 199 | for (const auto& cbuf : entries.const_buffers) { |
| 197 | source += | 200 | source += |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 47cc2011f..119073776 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "common/alignment.h" | 14 | #include "common/alignment.h" |
| 15 | #include "common/assert.h" | 15 | #include "common/assert.h" |
| 16 | #include "common/common_types.h" | 16 | #include "common/common_types.h" |
| 17 | #include "common/logging/log.h" | ||
| 17 | #include "video_core/engines/maxwell_3d.h" | 18 | #include "video_core/engines/maxwell_3d.h" |
| 18 | #include "video_core/renderer_opengl/gl_device.h" | 19 | #include "video_core/renderer_opengl/gl_device.h" |
| 19 | #include "video_core/renderer_opengl/gl_rasterizer.h" | 20 | #include "video_core/renderer_opengl/gl_rasterizer.h" |
| @@ -246,6 +247,8 @@ public: | |||
| 246 | usage.is_read, usage.is_written); | 247 | usage.is_read, usage.is_written); |
| 247 | } | 248 | } |
| 248 | entries.clip_distances = ir.GetClipDistances(); | 249 | entries.clip_distances = ir.GetClipDistances(); |
| 250 | entries.shader_viewport_layer_array = | ||
| 251 | stage == ShaderStage::Vertex && (ir.UsesLayer() || ir.UsesViewportIndex()); | ||
| 249 | entries.shader_length = ir.GetLength(); | 252 | entries.shader_length = ir.GetLength(); |
| 250 | return entries; | 253 | return entries; |
| 251 | } | 254 | } |
| @@ -282,22 +285,35 @@ private: | |||
| 282 | } | 285 | } |
| 283 | 286 | ||
| 284 | void DeclareVertexRedeclarations() { | 287 | void DeclareVertexRedeclarations() { |
| 285 | bool clip_distances_declared = false; | ||
| 286 | |||
| 287 | code.AddLine("out gl_PerVertex {{"); | 288 | code.AddLine("out gl_PerVertex {{"); |
| 288 | ++code.scope; | 289 | ++code.scope; |
| 289 | 290 | ||
| 290 | code.AddLine("vec4 gl_Position;"); | 291 | code.AddLine("vec4 gl_Position;"); |
| 291 | 292 | ||
| 292 | for (const auto o : ir.GetOutputAttributes()) { | 293 | for (const auto attribute : ir.GetOutputAttributes()) { |
| 293 | if (o == Attribute::Index::PointSize) | 294 | if (attribute == Attribute::Index::ClipDistances0123 || |
| 294 | code.AddLine("float gl_PointSize;"); | 295 | attribute == Attribute::Index::ClipDistances4567) { |
| 295 | if (!clip_distances_declared && (o == Attribute::Index::ClipDistances0123 || | ||
| 296 | o == Attribute::Index::ClipDistances4567)) { | ||
| 297 | code.AddLine("float gl_ClipDistance[];"); | 296 | code.AddLine("float gl_ClipDistance[];"); |
| 298 | clip_distances_declared = true; | 297 | break; |
| 299 | } | 298 | } |
| 300 | } | 299 | } |
| 300 | if (stage != ShaderStage::Vertex || device.HasVertexViewportLayer()) { | ||
| 301 | if (ir.UsesLayer()) { | ||
| 302 | code.AddLine("int gl_Layer;"); | ||
| 303 | } | ||
| 304 | if (ir.UsesViewportIndex()) { | ||
| 305 | code.AddLine("int gl_ViewportIndex;"); | ||
| 306 | } | ||
| 307 | } else if ((ir.UsesLayer() || ir.UsesViewportIndex()) && stage == ShaderStage::Vertex && | ||
| 308 | !device.HasVertexViewportLayer()) { | ||
| 309 | LOG_ERROR( | ||
| 310 | Render_OpenGL, | ||
| 311 | "GL_ARB_shader_viewport_layer_array is not available and its required by a shader"); | ||
| 312 | } | ||
| 313 | |||
| 314 | if (ir.UsesPointSize()) { | ||
| 315 | code.AddLine("float gl_PointSize;"); | ||
| 316 | } | ||
| 301 | 317 | ||
| 302 | --code.scope; | 318 | --code.scope; |
| 303 | code.AddLine("}};"); | 319 | code.AddLine("}};"); |
| @@ -805,6 +821,45 @@ private: | |||
| 805 | return CastOperand(VisitOperand(operation, operand_index), type); | 821 | return CastOperand(VisitOperand(operation, operand_index), type); |
| 806 | } | 822 | } |
| 807 | 823 | ||
| 824 | std::optional<std::pair<std::string, bool>> GetOutputAttribute(const AbufNode* abuf) { | ||
| 825 | switch (const auto attribute = abuf->GetIndex()) { | ||
| 826 | case Attribute::Index::Position: | ||
| 827 | return std::make_pair("gl_Position"s + GetSwizzle(abuf->GetElement()), false); | ||
| 828 | case Attribute::Index::LayerViewportPointSize: | ||
| 829 | switch (abuf->GetElement()) { | ||
| 830 | case 0: | ||
| 831 | UNIMPLEMENTED(); | ||
| 832 | return {}; | ||
| 833 | case 1: | ||
| 834 | if (stage == ShaderStage::Vertex && !device.HasVertexViewportLayer()) { | ||
| 835 | return {}; | ||
| 836 | } | ||
| 837 | return std::make_pair("gl_Layer", true); | ||
| 838 | case 2: | ||
| 839 | if (stage == ShaderStage::Vertex && !device.HasVertexViewportLayer()) { | ||
| 840 | return {}; | ||
| 841 | } | ||
| 842 | return std::make_pair("gl_ViewportIndex", true); | ||
| 843 | case 3: | ||
| 844 | UNIMPLEMENTED_MSG("Requires some state changes for gl_PointSize to work in shader"); | ||
| 845 | return std::make_pair("gl_PointSize", false); | ||
| 846 | } | ||
| 847 | return {}; | ||
| 848 | case Attribute::Index::ClipDistances0123: | ||
| 849 | return std::make_pair(fmt::format("gl_ClipDistance[{}]", abuf->GetElement()), false); | ||
| 850 | case Attribute::Index::ClipDistances4567: | ||
| 851 | return std::make_pair(fmt::format("gl_ClipDistance[{}]", abuf->GetElement() + 4), | ||
| 852 | false); | ||
| 853 | default: | ||
| 854 | if (IsGenericAttribute(attribute)) { | ||
| 855 | return std::make_pair( | ||
| 856 | GetOutputAttribute(attribute) + GetSwizzle(abuf->GetElement()), false); | ||
| 857 | } | ||
| 858 | UNIMPLEMENTED_MSG("Unhandled output attribute: {}", static_cast<u32>(attribute)); | ||
| 859 | return {}; | ||
| 860 | } | ||
| 861 | } | ||
| 862 | |||
| 808 | std::string CastOperand(const std::string& value, Type type) const { | 863 | std::string CastOperand(const std::string& value, Type type) const { |
| 809 | switch (type) { | 864 | switch (type) { |
| 810 | case Type::Bool: | 865 | case Type::Bool: |
| @@ -1001,6 +1056,8 @@ private: | |||
| 1001 | const Node& src = operation[1]; | 1056 | const Node& src = operation[1]; |
| 1002 | 1057 | ||
| 1003 | std::string target; | 1058 | std::string target; |
| 1059 | bool is_integer = false; | ||
| 1060 | |||
| 1004 | if (const auto gpr = std::get_if<GprNode>(&*dest)) { | 1061 | if (const auto gpr = std::get_if<GprNode>(&*dest)) { |
| 1005 | if (gpr->GetIndex() == Register::ZeroIndex) { | 1062 | if (gpr->GetIndex() == Register::ZeroIndex) { |
| 1006 | // Writing to Register::ZeroIndex is a no op | 1063 | // Writing to Register::ZeroIndex is a no op |
| @@ -1009,26 +1066,12 @@ private: | |||
| 1009 | target = GetRegister(gpr->GetIndex()); | 1066 | target = GetRegister(gpr->GetIndex()); |
| 1010 | } else if (const auto abuf = std::get_if<AbufNode>(&*dest)) { | 1067 | } else if (const auto abuf = std::get_if<AbufNode>(&*dest)) { |
| 1011 | UNIMPLEMENTED_IF(abuf->IsPhysicalBuffer()); | 1068 | UNIMPLEMENTED_IF(abuf->IsPhysicalBuffer()); |
| 1012 | 1069 | const auto result = GetOutputAttribute(abuf); | |
| 1013 | target = [&]() -> std::string { | 1070 | if (!result) { |
| 1014 | switch (const auto attribute = abuf->GetIndex(); abuf->GetIndex()) { | 1071 | return {}; |
| 1015 | case Attribute::Index::Position: | 1072 | } |
| 1016 | return "gl_Position"s + GetSwizzle(abuf->GetElement()); | 1073 | target = result->first; |
| 1017 | case Attribute::Index::PointSize: | 1074 | is_integer = result->second; |
| 1018 | return "gl_PointSize"; | ||
| 1019 | case Attribute::Index::ClipDistances0123: | ||
| 1020 | return fmt::format("gl_ClipDistance[{}]", abuf->GetElement()); | ||
| 1021 | case Attribute::Index::ClipDistances4567: | ||
| 1022 | return fmt::format("gl_ClipDistance[{}]", abuf->GetElement() + 4); | ||
| 1023 | default: | ||
| 1024 | if (IsGenericAttribute(attribute)) { | ||
| 1025 | return GetOutputAttribute(attribute) + GetSwizzle(abuf->GetElement()); | ||
| 1026 | } | ||
| 1027 | UNIMPLEMENTED_MSG("Unhandled output attribute: {}", | ||
| 1028 | static_cast<u32>(attribute)); | ||
| 1029 | return "0"; | ||
| 1030 | } | ||
| 1031 | }(); | ||
| 1032 | } else if (const auto lmem = std::get_if<LmemNode>(&*dest)) { | 1075 | } else if (const auto lmem = std::get_if<LmemNode>(&*dest)) { |
| 1033 | target = fmt::format("{}[ftou({}) / 4]", GetLocalMemory(), Visit(lmem->GetAddress())); | 1076 | target = fmt::format("{}[ftou({}) / 4]", GetLocalMemory(), Visit(lmem->GetAddress())); |
| 1034 | } else if (const auto gmem = std::get_if<GmemNode>(&*dest)) { | 1077 | } else if (const auto gmem = std::get_if<GmemNode>(&*dest)) { |
| @@ -1040,7 +1083,11 @@ private: | |||
| 1040 | UNREACHABLE_MSG("Assign called without a proper target"); | 1083 | UNREACHABLE_MSG("Assign called without a proper target"); |
| 1041 | } | 1084 | } |
| 1042 | 1085 | ||
| 1043 | code.AddLine("{} = {};", target, Visit(src)); | 1086 | if (is_integer) { |
| 1087 | code.AddLine("{} = ftoi({});", target, Visit(src)); | ||
| 1088 | } else { | ||
| 1089 | code.AddLine("{} = {};", target, Visit(src)); | ||
| 1090 | } | ||
| 1044 | return {}; | 1091 | return {}; |
| 1045 | } | 1092 | } |
| 1046 | 1093 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.h b/src/video_core/renderer_opengl/gl_shader_decompiler.h index 14d11c7fc..02586736d 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.h +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.h | |||
| @@ -78,6 +78,7 @@ struct ShaderEntries { | |||
| 78 | std::vector<ImageEntry> images; | 78 | std::vector<ImageEntry> images; |
| 79 | std::vector<GlobalMemoryEntry> global_memory_entries; | 79 | std::vector<GlobalMemoryEntry> global_memory_entries; |
| 80 | std::array<bool, Maxwell::NumClipDistances> clip_distances{}; | 80 | std::array<bool, Maxwell::NumClipDistances> clip_distances{}; |
| 81 | bool shader_viewport_layer_array{}; | ||
| 81 | std::size_t shader_length{}; | 82 | std::size_t shader_length{}; |
| 82 | }; | 83 | }; |
| 83 | 84 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp index 10688397b..7893d1e26 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp | |||
| @@ -373,6 +373,12 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn | |||
| 373 | } | 373 | } |
| 374 | } | 374 | } |
| 375 | 375 | ||
| 376 | bool shader_viewport_layer_array{}; | ||
| 377 | if (!LoadObjectFromPrecompiled(shader_viewport_layer_array)) { | ||
| 378 | return {}; | ||
| 379 | } | ||
| 380 | entry.entries.shader_viewport_layer_array = shader_viewport_layer_array; | ||
| 381 | |||
| 376 | u64 shader_length{}; | 382 | u64 shader_length{}; |
| 377 | if (!LoadObjectFromPrecompiled(shader_length)) { | 383 | if (!LoadObjectFromPrecompiled(shader_length)) { |
| 378 | return {}; | 384 | return {}; |
| @@ -445,6 +451,10 @@ bool ShaderDiskCacheOpenGL::SaveDecompiledFile(u64 unique_identifier, const std: | |||
| 445 | } | 451 | } |
| 446 | } | 452 | } |
| 447 | 453 | ||
| 454 | if (!SaveObjectToPrecompiled(entries.shader_viewport_layer_array)) { | ||
| 455 | return false; | ||
| 456 | } | ||
| 457 | |||
| 448 | if (!SaveObjectToPrecompiled(static_cast<u64>(entries.shader_length))) { | 458 | if (!SaveObjectToPrecompiled(static_cast<u64>(entries.shader_length))) { |
| 449 | return false; | 459 | return false; |
| 450 | } | 460 | } |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 1bb04607b..9b2d8e987 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -430,20 +430,17 @@ private: | |||
| 430 | instance_index = DeclareBuiltIn(spv::BuiltIn::InstanceIndex, spv::StorageClass::Input, | 430 | instance_index = DeclareBuiltIn(spv::BuiltIn::InstanceIndex, spv::StorageClass::Input, |
| 431 | t_in_uint, "instance_index"); | 431 | t_in_uint, "instance_index"); |
| 432 | 432 | ||
| 433 | bool is_point_size_declared = false; | ||
| 434 | bool is_clip_distances_declared = false; | 433 | bool is_clip_distances_declared = false; |
| 435 | for (const auto index : ir.GetOutputAttributes()) { | 434 | for (const auto index : ir.GetOutputAttributes()) { |
| 436 | if (index == Attribute::Index::PointSize) { | 435 | if (index == Attribute::Index::ClipDistances0123 || |
| 437 | is_point_size_declared = true; | 436 | index == Attribute::Index::ClipDistances4567) { |
| 438 | } else if (index == Attribute::Index::ClipDistances0123 || | ||
| 439 | index == Attribute::Index::ClipDistances4567) { | ||
| 440 | is_clip_distances_declared = true; | 437 | is_clip_distances_declared = true; |
| 441 | } | 438 | } |
| 442 | } | 439 | } |
| 443 | 440 | ||
| 444 | std::vector<Id> members; | 441 | std::vector<Id> members; |
| 445 | members.push_back(t_float4); | 442 | members.push_back(t_float4); |
| 446 | if (is_point_size_declared) { | 443 | if (ir.UsesPointSize()) { |
| 447 | members.push_back(t_float); | 444 | members.push_back(t_float); |
| 448 | } | 445 | } |
| 449 | if (is_clip_distances_declared) { | 446 | if (is_clip_distances_declared) { |
| @@ -466,7 +463,7 @@ private: | |||
| 466 | 463 | ||
| 467 | position_index = MemberDecorateBuiltIn(spv::BuiltIn::Position, "position", true); | 464 | position_index = MemberDecorateBuiltIn(spv::BuiltIn::Position, "position", true); |
| 468 | point_size_index = | 465 | point_size_index = |
| 469 | MemberDecorateBuiltIn(spv::BuiltIn::PointSize, "point_size", is_point_size_declared); | 466 | MemberDecorateBuiltIn(spv::BuiltIn::PointSize, "point_size", ir.UsesPointSize()); |
| 470 | clip_distances_index = MemberDecorateBuiltIn(spv::BuiltIn::ClipDistance, "clip_distances", | 467 | clip_distances_index = MemberDecorateBuiltIn(spv::BuiltIn::ClipDistance, "clip_distances", |
| 471 | is_clip_distances_declared); | 468 | is_clip_distances_declared); |
| 472 | 469 | ||
| @@ -712,7 +709,8 @@ private: | |||
| 712 | case Attribute::Index::Position: | 709 | case Attribute::Index::Position: |
| 713 | return AccessElement(t_out_float, per_vertex, position_index, | 710 | return AccessElement(t_out_float, per_vertex, position_index, |
| 714 | abuf->GetElement()); | 711 | abuf->GetElement()); |
| 715 | case Attribute::Index::PointSize: | 712 | case Attribute::Index::LayerViewportPointSize: |
| 713 | UNIMPLEMENTED_IF(abuf->GetElement() != 3); | ||
| 716 | return AccessElement(t_out_float, per_vertex, point_size_index); | 714 | return AccessElement(t_out_float, per_vertex, point_size_index); |
| 717 | case Attribute::Index::ClipDistances0123: | 715 | case Attribute::Index::ClipDistances0123: |
| 718 | return AccessElement(t_out_float, per_vertex, clip_distances_index, | 716 | return AccessElement(t_out_float, per_vertex, clip_distances_index, |
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index 5994bfc4e..caa409788 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp | |||
| @@ -89,6 +89,22 @@ Node ShaderIR::GetPhysicalInputAttribute(Tegra::Shader::Register physical_addres | |||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) { | 91 | Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) { |
| 92 | if (index == Attribute::Index::LayerViewportPointSize) { | ||
| 93 | switch (element) { | ||
| 94 | case 0: | ||
| 95 | UNIMPLEMENTED(); | ||
| 96 | break; | ||
| 97 | case 1: | ||
| 98 | uses_layer = true; | ||
| 99 | break; | ||
| 100 | case 2: | ||
| 101 | uses_viewport_index = true; | ||
| 102 | break; | ||
| 103 | case 3: | ||
| 104 | uses_point_size = true; | ||
| 105 | break; | ||
| 106 | } | ||
| 107 | } | ||
| 92 | if (index == Attribute::Index::ClipDistances0123 || | 108 | if (index == Attribute::Index::ClipDistances0123 || |
| 93 | index == Attribute::Index::ClipDistances4567) { | 109 | index == Attribute::Index::ClipDistances4567) { |
| 94 | const auto clip_index = | 110 | const auto clip_index = |
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 6145f0a70..03c888def 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -115,6 +115,18 @@ public: | |||
| 115 | return static_cast<std::size_t>(coverage_end * sizeof(u64)); | 115 | return static_cast<std::size_t>(coverage_end * sizeof(u64)); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | bool UsesLayer() const { | ||
| 119 | return uses_layer; | ||
| 120 | } | ||
| 121 | |||
| 122 | bool UsesViewportIndex() const { | ||
| 123 | return uses_viewport_index; | ||
| 124 | } | ||
| 125 | |||
| 126 | bool UsesPointSize() const { | ||
| 127 | return uses_point_size; | ||
| 128 | } | ||
| 129 | |||
| 118 | bool HasPhysicalAttributes() const { | 130 | bool HasPhysicalAttributes() const { |
| 119 | return uses_physical_attributes; | 131 | return uses_physical_attributes; |
| 120 | } | 132 | } |
| @@ -346,6 +358,9 @@ private: | |||
| 346 | std::set<Image> used_images; | 358 | std::set<Image> used_images; |
| 347 | std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances> used_clip_distances{}; | 359 | std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances> used_clip_distances{}; |
| 348 | std::map<GlobalMemoryBase, GlobalMemoryUsage> used_global_memory; | 360 | std::map<GlobalMemoryBase, GlobalMemoryUsage> used_global_memory; |
| 361 | bool uses_layer{}; | ||
| 362 | bool uses_viewport_index{}; | ||
| 363 | bool uses_point_size{}; | ||
| 349 | bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes | 364 | bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes |
| 350 | 365 | ||
| 351 | Tegra::Shader::Header header; | 366 | Tegra::Shader::Header header; |