diff options
| author | 2019-03-14 02:47:09 -0300 | |
|---|---|---|
| committer | 2019-04-10 14:20:25 -0300 | |
| commit | 58ad8dfac61c6532ebfb69179ed82f812a104a8a (patch) | |
| tree | 312979f5972bc8a336afc953a8d43e1e78d1b484 /src | |
| parent | vk_shader_decompiler: Implement texture decompilation helper functions (diff) | |
| download | yuzu-58ad8dfac61c6532ebfb69179ed82f812a104a8a.tar.gz yuzu-58ad8dfac61c6532ebfb69179ed82f812a104a8a.tar.xz yuzu-58ad8dfac61c6532ebfb69179ed82f812a104a8a.zip | |
vk_shader_decompiler: Implement most common texture primitives
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 73 |
1 files changed, 65 insertions, 8 deletions
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 3f23ba749..6c5c6500a 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -836,24 +836,81 @@ private: | |||
| 836 | : Emit(OpCompositeConstruct(t_float_lut.at(coords.size() - 1), coords)); | 836 | : Emit(OpCompositeConstruct(t_float_lut.at(coords.size() - 1), coords)); |
| 837 | } | 837 | } |
| 838 | 838 | ||
| 839 | Id GetTextureElement(Operation operation, Id sample_value) { | ||
| 840 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); | ||
| 841 | ASSERT(meta); | ||
| 842 | return Emit(OpCompositeExtract(t_float, sample_value, meta->element)); | ||
| 843 | } | ||
| 844 | |||
| 839 | Id Texture(Operation operation) { | 845 | Id Texture(Operation operation) { |
| 840 | UNIMPLEMENTED(); | 846 | const Id texture = Emit(OpImageSampleImplicitLod(t_float4, GetTextureSampler(operation), |
| 841 | return {}; | 847 | GetTextureCoordinates(operation))); |
| 848 | return GetTextureElement(operation, texture); | ||
| 842 | } | 849 | } |
| 843 | 850 | ||
| 844 | Id TextureLod(Operation operation) { | 851 | Id TextureLod(Operation operation) { |
| 845 | UNIMPLEMENTED(); | 852 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
| 846 | return {}; | 853 | const Id texture = Emit(OpImageSampleExplicitLod( |
| 854 | t_float4, GetTextureSampler(operation), GetTextureCoordinates(operation), | ||
| 855 | spv::ImageOperandsMask::Lod, Visit(meta->lod))); | ||
| 856 | return GetTextureElement(operation, texture); | ||
| 847 | } | 857 | } |
| 848 | 858 | ||
| 849 | Id TextureGather(Operation operation) { | 859 | Id TextureGather(Operation operation) { |
| 850 | UNIMPLEMENTED(); | 860 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
| 851 | return {}; | 861 | const auto coords = GetTextureCoordinates(operation); |
| 862 | |||
| 863 | Id texture; | ||
| 864 | if (meta->sampler.IsShadow()) { | ||
| 865 | texture = Emit(OpImageDrefGather(t_float4, GetTextureSampler(operation), coords, | ||
| 866 | Visit(meta->component))); | ||
| 867 | } else { | ||
| 868 | u32 component_value = 0; | ||
| 869 | if (meta->component) { | ||
| 870 | const auto component = std::get_if<ImmediateNode>(meta->component); | ||
| 871 | ASSERT_MSG(component, "Component is not an immediate value"); | ||
| 872 | component_value = component->GetValue(); | ||
| 873 | } | ||
| 874 | texture = Emit(OpImageGather(t_float4, GetTextureSampler(operation), coords, | ||
| 875 | Constant(t_uint, component_value))); | ||
| 876 | } | ||
| 877 | |||
| 878 | return GetTextureElement(operation, texture); | ||
| 852 | } | 879 | } |
| 853 | 880 | ||
| 854 | Id TextureQueryDimensions(Operation operation) { | 881 | Id TextureQueryDimensions(Operation operation) { |
| 855 | UNIMPLEMENTED(); | 882 | const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); |
| 856 | return {}; | 883 | const auto image_id = GetTextureImage(operation); |
| 884 | AddCapability(spv::Capability::ImageQuery); | ||
| 885 | |||
| 886 | if (meta->element == 3) { | ||
| 887 | return BitcastTo<Type::Float>(Emit(OpImageQueryLevels(t_int, image_id))); | ||
| 888 | } | ||
| 889 | |||
| 890 | const Id lod = VisitOperand<Type::Uint>(operation, 0); | ||
| 891 | const std::size_t coords_count = [&]() { | ||
| 892 | switch (const auto type = meta->sampler.GetType(); type) { | ||
| 893 | case Tegra::Shader::TextureType::Texture1D: | ||
| 894 | return 1; | ||
| 895 | case Tegra::Shader::TextureType::Texture2D: | ||
| 896 | case Tegra::Shader::TextureType::TextureCube: | ||
| 897 | return 2; | ||
| 898 | case Tegra::Shader::TextureType::Texture3D: | ||
| 899 | return 3; | ||
| 900 | default: | ||
| 901 | UNREACHABLE_MSG("Invalid texture type={}", static_cast<u32>(type)); | ||
| 902 | return 2; | ||
| 903 | } | ||
| 904 | }(); | ||
| 905 | |||
| 906 | if (meta->element >= coords_count) { | ||
| 907 | return Constant(t_float, 0.0f); | ||
| 908 | } | ||
| 909 | |||
| 910 | const std::array<Id, 3> types = {t_int, t_int2, t_int3}; | ||
| 911 | const Id sizes = Emit(OpImageQuerySizeLod(types.at(coords_count - 1), image_id, lod)); | ||
| 912 | const Id size = Emit(OpCompositeExtract(t_int, sizes, meta->element)); | ||
| 913 | return BitcastTo<Type::Float>(size); | ||
| 857 | } | 914 | } |
| 858 | 915 | ||
| 859 | Id TextureQueryLod(Operation operation) { | 916 | Id TextureQueryLod(Operation operation) { |