diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 56 | ||||
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 37 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 4 |
4 files changed, 65 insertions, 40 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index d14cd5f20..f62ae8801 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -325,11 +325,11 @@ enum class TextureQueryType : u64 { | |||
| 325 | 325 | ||
| 326 | enum class TextureProcessMode : u64 { | 326 | enum class TextureProcessMode : u64 { |
| 327 | None = 0, | 327 | None = 0, |
| 328 | LZ = 1, // Unknown, appears to be the same as none. | 328 | LZ = 1, // Load LOD of zero. |
| 329 | LB = 2, // Load Bias. | 329 | LB = 2, // Load Bias. |
| 330 | LL = 3, // Load LOD (LevelOfDetail) | 330 | LL = 3, // Load LOD. |
| 331 | LBA = 6, // Load Bias. The A is unknown, does not appear to differ with LB | 331 | LBA = 6, // Load Bias. The A is unknown, does not appear to differ with LB. |
| 332 | LLA = 7 // Load LOD. The A is unknown, does not appear to differ with LL | 332 | LLA = 7 // Load LOD. The A is unknown, does not appear to differ with LL. |
| 333 | }; | 333 | }; |
| 334 | 334 | ||
| 335 | enum class TextureMiscMode : u64 { | 335 | enum class TextureMiscMode : u64 { |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 72ff6ac6a..11d1169f0 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -5,7 +5,9 @@ | |||
| 5 | #include <array> | 5 | #include <array> |
| 6 | #include <string> | 6 | #include <string> |
| 7 | #include <string_view> | 7 | #include <string_view> |
| 8 | #include <utility> | ||
| 8 | #include <variant> | 9 | #include <variant> |
| 10 | #include <vector> | ||
| 9 | 11 | ||
| 10 | #include <fmt/format.h> | 12 | #include <fmt/format.h> |
| 11 | 13 | ||
| @@ -717,7 +719,7 @@ private: | |||
| 717 | } | 719 | } |
| 718 | 720 | ||
| 719 | std::string GenerateTexture(Operation operation, const std::string& func, | 721 | std::string GenerateTexture(Operation operation, const std::string& func, |
| 720 | bool is_extra_int = false) { | 722 | const std::vector<std::pair<Type, Node>>& extras) { |
| 721 | constexpr std::array<const char*, 4> coord_constructors = {"float", "vec2", "vec3", "vec4"}; | 723 | constexpr std::array<const char*, 4> coord_constructors = {"float", "vec2", "vec3", "vec4"}; |
| 722 | 724 | ||
| 723 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); | 725 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
| @@ -738,36 +740,47 @@ private: | |||
| 738 | expr += Visit(operation[i]); | 740 | expr += Visit(operation[i]); |
| 739 | 741 | ||
| 740 | const std::size_t next = i + 1; | 742 | const std::size_t next = i + 1; |
| 741 | if (next < count || has_array || has_shadow) | 743 | if (next < count) |
| 742 | expr += ", "; | 744 | expr += ", "; |
| 743 | } | 745 | } |
| 744 | if (has_array) { | 746 | if (has_array) { |
| 745 | expr += "float(ftoi(" + Visit(meta->array) + "))"; | 747 | expr += ", float(ftoi(" + Visit(meta->array) + "))"; |
| 746 | } | 748 | } |
| 747 | if (has_shadow) { | 749 | if (has_shadow) { |
| 748 | if (has_array) | 750 | expr += ", " + Visit(meta->depth_compare); |
| 749 | expr += ", "; | ||
| 750 | expr += Visit(meta->depth_compare); | ||
| 751 | } | 751 | } |
| 752 | expr += ')'; | 752 | expr += ')'; |
| 753 | 753 | ||
| 754 | for (const Node extra : meta->extras) { | 754 | for (const auto& extra_pair : extras) { |
| 755 | const auto [type, operand] = extra_pair; | ||
| 756 | if (operand == nullptr) { | ||
| 757 | continue; | ||
| 758 | } | ||
| 755 | expr += ", "; | 759 | expr += ", "; |
| 756 | if (is_extra_int) { | 760 | |
| 757 | if (const auto immediate = std::get_if<ImmediateNode>(extra)) { | 761 | switch (type) { |
| 762 | case Type::Int: | ||
| 763 | if (const auto immediate = std::get_if<ImmediateNode>(operand)) { | ||
| 758 | // Inline the string as an immediate integer in GLSL (some extra arguments are | 764 | // Inline the string as an immediate integer in GLSL (some extra arguments are |
| 759 | // required to be constant) | 765 | // required to be constant) |
| 760 | expr += std::to_string(static_cast<s32>(immediate->GetValue())); | 766 | expr += std::to_string(static_cast<s32>(immediate->GetValue())); |
| 761 | } else { | 767 | } else { |
| 762 | expr += "ftoi(" + Visit(extra) + ')'; | 768 | expr += "ftoi(" + Visit(operand) + ')'; |
| 763 | } | 769 | } |
| 764 | } else { | 770 | break; |
| 765 | expr += Visit(extra); | 771 | case Type::Float: |
| 772 | expr += Visit(operand); | ||
| 773 | break; | ||
| 774 | default: { | ||
| 775 | const auto type_int = static_cast<u32>(type); | ||
| 776 | UNIMPLEMENTED_MSG("Unimplemented extra type={}", type_int); | ||
| 777 | expr += '0'; | ||
| 778 | break; | ||
| 779 | } | ||
| 766 | } | 780 | } |
| 767 | } | 781 | } |
| 768 | 782 | ||
| 769 | expr += ')'; | 783 | return expr + ')'; |
| 770 | return expr; | ||
| 771 | } | 784 | } |
| 772 | 785 | ||
| 773 | std::string Assign(Operation operation) { | 786 | std::string Assign(Operation operation) { |
| @@ -1146,7 +1159,7 @@ private: | |||
| 1146 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); | 1159 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
| 1147 | ASSERT(meta); | 1160 | ASSERT(meta); |
| 1148 | 1161 | ||
| 1149 | std::string expr = GenerateTexture(operation, "texture"); | 1162 | std::string expr = GenerateTexture(operation, "texture", {{Type::Float, meta->bias}}); |
| 1150 | if (meta->sampler.IsShadow()) { | 1163 | if (meta->sampler.IsShadow()) { |
| 1151 | expr = "vec4(" + expr + ')'; | 1164 | expr = "vec4(" + expr + ')'; |
| 1152 | } | 1165 | } |
| @@ -1157,7 +1170,7 @@ private: | |||
| 1157 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); | 1170 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
| 1158 | ASSERT(meta); | 1171 | ASSERT(meta); |
| 1159 | 1172 | ||
| 1160 | std::string expr = GenerateTexture(operation, "textureLod"); | 1173 | std::string expr = GenerateTexture(operation, "textureLod", {{Type::Float, meta->lod}}); |
| 1161 | if (meta->sampler.IsShadow()) { | 1174 | if (meta->sampler.IsShadow()) { |
| 1162 | expr = "vec4(" + expr + ')'; | 1175 | expr = "vec4(" + expr + ')'; |
| 1163 | } | 1176 | } |
| @@ -1168,7 +1181,8 @@ private: | |||
| 1168 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); | 1181 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
| 1169 | ASSERT(meta); | 1182 | ASSERT(meta); |
| 1170 | 1183 | ||
| 1171 | return GenerateTexture(operation, "textureGather", !meta->sampler.IsShadow()) + | 1184 | const auto type = meta->sampler.IsShadow() ? Type::Float : Type::Int; |
| 1185 | return GenerateTexture(operation, "textureGather", {{type, meta->component}}) + | ||
| 1172 | GetSwizzle(meta->element); | 1186 | GetSwizzle(meta->element); |
| 1173 | } | 1187 | } |
| 1174 | 1188 | ||
| @@ -1197,8 +1211,8 @@ private: | |||
| 1197 | ASSERT(meta); | 1211 | ASSERT(meta); |
| 1198 | 1212 | ||
| 1199 | if (meta->element < 2) { | 1213 | if (meta->element < 2) { |
| 1200 | return "itof(int((" + GenerateTexture(operation, "textureQueryLod") + " * vec2(256))" + | 1214 | return "itof(int((" + GenerateTexture(operation, "textureQueryLod", {}) + |
| 1201 | GetSwizzle(meta->element) + "))"; | 1215 | " * vec2(256))" + GetSwizzle(meta->element) + "))"; |
| 1202 | } | 1216 | } |
| 1203 | return "0"; | 1217 | return "0"; |
| 1204 | } | 1218 | } |
| @@ -1224,9 +1238,9 @@ private: | |||
| 1224 | else if (next < count) | 1238 | else if (next < count) |
| 1225 | expr += ", "; | 1239 | expr += ", "; |
| 1226 | } | 1240 | } |
| 1227 | for (std::size_t i = 0; i < meta->extras.size(); ++i) { | 1241 | if (meta->lod) { |
| 1228 | expr += ", "; | 1242 | expr += ", "; |
| 1229 | expr += CastOperand(Visit(meta->extras.at(i)), Type::Int); | 1243 | expr += CastOperand(Visit(meta->lod), Type::Int); |
| 1230 | } | 1244 | } |
| 1231 | expr += ')'; | 1245 | expr += ')'; |
| 1232 | 1246 | ||
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index 50e2d0584..a99ae19bf 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp | |||
| @@ -119,8 +119,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 119 | coords.push_back(op_a); | 119 | coords.push_back(op_a); |
| 120 | coords.push_back(op_b); | 120 | coords.push_back(op_b); |
| 121 | } | 121 | } |
| 122 | std::vector<Node> extras; | 122 | const Node component = Immediate(static_cast<u32>(instr.tld4s.component)); |
| 123 | extras.push_back(Immediate(static_cast<u32>(instr.tld4s.component))); | ||
| 124 | 123 | ||
| 125 | const auto& sampler = | 124 | const auto& sampler = |
| 126 | GetSampler(instr.sampler, TextureType::Texture2D, false, depth_compare); | 125 | GetSampler(instr.sampler, TextureType::Texture2D, false, depth_compare); |
| @@ -128,7 +127,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 128 | Node4 values; | 127 | Node4 values; |
| 129 | for (u32 element = 0; element < values.size(); ++element) { | 128 | for (u32 element = 0; element < values.size(); ++element) { |
| 130 | auto coords_copy = coords; | 129 | auto coords_copy = coords; |
| 131 | MetaTexture meta{sampler, {}, {}, extras, element}; | 130 | MetaTexture meta{sampler, {}, {}, {}, {}, component, element}; |
| 132 | values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); | 131 | values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); |
| 133 | } | 132 | } |
| 134 | 133 | ||
| @@ -153,7 +152,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 153 | if (!instr.txq.IsComponentEnabled(element)) { | 152 | if (!instr.txq.IsComponentEnabled(element)) { |
| 154 | continue; | 153 | continue; |
| 155 | } | 154 | } |
| 156 | MetaTexture meta{sampler, {}, {}, {}, element}; | 155 | MetaTexture meta{sampler, {}, {}, {}, {}, {}, element}; |
| 157 | const Node value = | 156 | const Node value = |
| 158 | Operation(OperationCode::TextureQueryDimensions, meta, GetRegister(instr.gpr8)); | 157 | Operation(OperationCode::TextureQueryDimensions, meta, GetRegister(instr.gpr8)); |
| 159 | SetTemporal(bb, indexer++, value); | 158 | SetTemporal(bb, indexer++, value); |
| @@ -203,7 +202,7 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) { | |||
| 203 | 202 | ||
| 204 | for (u32 element = 0; element < 2; ++element) { | 203 | for (u32 element = 0; element < 2; ++element) { |
| 205 | auto params = coords; | 204 | auto params = coords; |
| 206 | MetaTexture meta{sampler, {}, {}, {}, element}; | 205 | MetaTexture meta{sampler, {}, {}, {}, {}, {}, element}; |
| 207 | const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); | 206 | const Node value = Operation(OperationCode::TextureQueryLod, meta, std::move(params)); |
| 208 | SetTemporal(bb, element, value); | 207 | SetTemporal(bb, element, value); |
| 209 | } | 208 | } |
| @@ -347,25 +346,35 @@ Node4 ShaderIR::GetTextureCode(Instruction instr, TextureType texture_type, | |||
| 347 | (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow)); | 346 | (texture_type == Tegra::Shader::TextureType::TextureCube && is_array && is_shadow)); |
| 348 | 347 | ||
| 349 | const OperationCode read_method = | 348 | const OperationCode read_method = |
| 350 | lod_needed && gl_lod_supported ? OperationCode::TextureLod : OperationCode::Texture; | 349 | (lod_needed && gl_lod_supported) ? OperationCode::TextureLod : OperationCode::Texture; |
| 351 | 350 | ||
| 352 | UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported); | 351 | UNIMPLEMENTED_IF(process_mode != TextureProcessMode::None && !gl_lod_supported); |
| 353 | 352 | ||
| 354 | std::vector<Node> extras; | 353 | Node bias = {}; |
| 354 | Node lod = {}; | ||
| 355 | if (process_mode != TextureProcessMode::None && gl_lod_supported) { | 355 | if (process_mode != TextureProcessMode::None && gl_lod_supported) { |
| 356 | if (process_mode == TextureProcessMode::LZ) { | 356 | switch (process_mode) { |
| 357 | extras.push_back(Immediate(0.0f)); | 357 | case TextureProcessMode::LZ: |
| 358 | } else { | 358 | lod = Immediate(0.0f); |
| 359 | break; | ||
| 360 | case TextureProcessMode::LB: | ||
| 359 | // If present, lod or bias are always stored in the register indexed by the gpr20 | 361 | // If present, lod or bias are always stored in the register indexed by the gpr20 |
| 360 | // field with an offset depending on the usage of the other registers | 362 | // field with an offset depending on the usage of the other registers |
| 361 | extras.push_back(GetRegister(instr.gpr20.Value() + bias_offset)); | 363 | bias = GetRegister(instr.gpr20.Value() + bias_offset); |
| 364 | break; | ||
| 365 | case TextureProcessMode::LL: | ||
| 366 | lod = GetRegister(instr.gpr20.Value() + bias_offset); | ||
| 367 | break; | ||
| 368 | default: | ||
| 369 | UNIMPLEMENTED_MSG("Unimplemented process mode={}", static_cast<u32>(process_mode)); | ||
| 370 | break; | ||
| 362 | } | 371 | } |
| 363 | } | 372 | } |
| 364 | 373 | ||
| 365 | Node4 values; | 374 | Node4 values; |
| 366 | for (u32 element = 0; element < values.size(); ++element) { | 375 | for (u32 element = 0; element < values.size(); ++element) { |
| 367 | auto copy_coords = coords; | 376 | auto copy_coords = coords; |
| 368 | MetaTexture meta{sampler, array, depth_compare, extras, element}; | 377 | MetaTexture meta{sampler, array, depth_compare, bias, lod, {}, element}; |
| 369 | values[element] = Operation(read_method, meta, std::move(copy_coords)); | 378 | values[element] = Operation(read_method, meta, std::move(copy_coords)); |
| 370 | } | 379 | } |
| 371 | 380 | ||
| @@ -462,7 +471,7 @@ Node4 ShaderIR::GetTld4Code(Instruction instr, TextureType texture_type, bool de | |||
| 462 | Node4 values; | 471 | Node4 values; |
| 463 | for (u32 element = 0; element < values.size(); ++element) { | 472 | for (u32 element = 0; element < values.size(); ++element) { |
| 464 | auto coords_copy = coords; | 473 | auto coords_copy = coords; |
| 465 | MetaTexture meta{sampler, GetRegister(array_register), {}, {}, element}; | 474 | MetaTexture meta{sampler, GetRegister(array_register), {}, {}, {}, {}, element}; |
| 466 | values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); | 475 | values[element] = Operation(OperationCode::TextureGather, meta, std::move(coords_copy)); |
| 467 | } | 476 | } |
| 468 | 477 | ||
| @@ -498,7 +507,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is | |||
| 498 | Node4 values; | 507 | Node4 values; |
| 499 | for (u32 element = 0; element < values.size(); ++element) { | 508 | for (u32 element = 0; element < values.size(); ++element) { |
| 500 | auto coords_copy = coords; | 509 | auto coords_copy = coords; |
| 501 | MetaTexture meta{sampler, array, {}, {lod}, element}; | 510 | MetaTexture meta{sampler, array, {}, {}, lod, {}, element}; |
| 502 | values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); | 511 | values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); |
| 503 | } | 512 | } |
| 504 | return values; | 513 | return values; |
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 0548c46f0..5bc3a3900 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -290,7 +290,9 @@ struct MetaTexture { | |||
| 290 | const Sampler& sampler; | 290 | const Sampler& sampler; |
| 291 | Node array{}; | 291 | Node array{}; |
| 292 | Node depth_compare{}; | 292 | Node depth_compare{}; |
| 293 | std::vector<Node> extras; | 293 | Node bias{}; |
| 294 | Node lod{}; | ||
| 295 | Node component{}; | ||
| 294 | u32 element{}; | 296 | u32 element{}; |
| 295 | }; | 297 | }; |
| 296 | 298 | ||