diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 31 | ||||
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/shader/decode/texture.cpp | 11 |
3 files changed, 34 insertions, 9 deletions
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 40e2e0d38..c6846d886 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -1845,13 +1845,21 @@ private: | |||
| 1845 | 1845 | ||
| 1846 | Expression TextureGather(Operation operation) { | 1846 | Expression TextureGather(Operation operation) { |
| 1847 | const auto& meta = std::get<MetaTexture>(operation.GetMeta()); | 1847 | const auto& meta = std::get<MetaTexture>(operation.GetMeta()); |
| 1848 | UNIMPLEMENTED_IF(!meta.aoffi.empty()); | ||
| 1849 | 1848 | ||
| 1850 | const Id coords = GetCoordinates(operation, Type::Float); | 1849 | const Id coords = GetCoordinates(operation, Type::Float); |
| 1850 | |||
| 1851 | spv::ImageOperandsMask mask = spv::ImageOperandsMask::MaskNone; | ||
| 1852 | std::vector<Id> operands; | ||
| 1851 | Id texture{}; | 1853 | Id texture{}; |
| 1854 | |||
| 1855 | if (!meta.aoffi.empty()) { | ||
| 1856 | mask = mask | spv::ImageOperandsMask::Offset; | ||
| 1857 | operands.push_back(GetOffsetCoordinates(operation)); | ||
| 1858 | } | ||
| 1859 | |||
| 1852 | if (meta.sampler.is_shadow) { | 1860 | if (meta.sampler.is_shadow) { |
| 1853 | texture = OpImageDrefGather(t_float4, GetTextureSampler(operation), coords, | 1861 | texture = OpImageDrefGather(t_float4, GetTextureSampler(operation), coords, |
| 1854 | AsFloat(Visit(meta.depth_compare))); | 1862 | AsFloat(Visit(meta.depth_compare)), mask, operands); |
| 1855 | } else { | 1863 | } else { |
| 1856 | u32 component_value = 0; | 1864 | u32 component_value = 0; |
| 1857 | if (meta.component) { | 1865 | if (meta.component) { |
| @@ -1860,7 +1868,7 @@ private: | |||
| 1860 | component_value = component->GetValue(); | 1868 | component_value = component->GetValue(); |
| 1861 | } | 1869 | } |
| 1862 | texture = OpImageGather(t_float4, GetTextureSampler(operation), coords, | 1870 | texture = OpImageGather(t_float4, GetTextureSampler(operation), coords, |
| 1863 | Constant(t_uint, component_value)); | 1871 | Constant(t_uint, component_value), mask, operands); |
| 1864 | } | 1872 | } |
| 1865 | return GetTextureElement(operation, texture, Type::Float); | 1873 | return GetTextureElement(operation, texture, Type::Float); |
| 1866 | } | 1874 | } |
| @@ -1928,13 +1936,22 @@ private: | |||
| 1928 | 1936 | ||
| 1929 | const Id image = GetTextureImage(operation); | 1937 | const Id image = GetTextureImage(operation); |
| 1930 | const Id coords = GetCoordinates(operation, Type::Int); | 1938 | const Id coords = GetCoordinates(operation, Type::Int); |
| 1939 | |||
| 1940 | spv::ImageOperandsMask mask = spv::ImageOperandsMask::MaskNone; | ||
| 1941 | std::vector<Id> operands; | ||
| 1931 | Id fetch; | 1942 | Id fetch; |
| 1943 | |||
| 1932 | if (meta.lod && !meta.sampler.is_buffer) { | 1944 | if (meta.lod && !meta.sampler.is_buffer) { |
| 1933 | fetch = OpImageFetch(t_float4, image, coords, spv::ImageOperandsMask::Lod, | 1945 | mask = mask | spv::ImageOperandsMask::Lod; |
| 1934 | AsInt(Visit(meta.lod))); | 1946 | operands.push_back(AsInt(Visit(meta.lod))); |
| 1935 | } else { | 1947 | } |
| 1936 | fetch = OpImageFetch(t_float4, image, coords); | 1948 | |
| 1949 | if (!meta.aoffi.empty()) { | ||
| 1950 | mask = mask | spv::ImageOperandsMask::Offset; | ||
| 1951 | operands.push_back(GetOffsetCoordinates(operation)); | ||
| 1937 | } | 1952 | } |
| 1953 | |||
| 1954 | fetch = OpImageFetch(t_float4, image, coords, mask, operands); | ||
| 1938 | return GetTextureElement(operation, fetch, Type::Float); | 1955 | return GetTextureElement(operation, fetch, Type::Float); |
| 1939 | } | 1956 | } |
| 1940 | 1957 | ||
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 50f4e7d35..7728f600e 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp | |||
| @@ -330,6 +330,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 330 | case StoreType::Bits32: | 330 | case StoreType::Bits32: |
| 331 | (this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0)); | 331 | (this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0)); |
| 332 | break; | 332 | break; |
| 333 | case StoreType::Unsigned16: | ||
| 333 | case StoreType::Signed16: { | 334 | case StoreType::Signed16: { |
| 334 | Node address = GetAddress(0); | 335 | Node address = GetAddress(0); |
| 335 | Node memory = (this->*get_memory)(address); | 336 | Node memory = (this->*get_memory)(address); |
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp index 833fa2a39..c69681e8d 100644 --- a/src/video_core/shader/decode/texture.cpp +++ b/src/video_core/shader/decode/texture.cpp | |||
| @@ -806,6 +806,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is | |||
| 806 | 806 | ||
| 807 | const std::size_t type_coord_count = GetCoordCount(texture_type); | 807 | const std::size_t type_coord_count = GetCoordCount(texture_type); |
| 808 | const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL; | 808 | const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL; |
| 809 | const bool aoffi_enabled = instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI); | ||
| 809 | 810 | ||
| 810 | // If enabled arrays index is always stored in the gpr8 field | 811 | // If enabled arrays index is always stored in the gpr8 field |
| 811 | const u64 array_register = instr.gpr8.Value(); | 812 | const u64 array_register = instr.gpr8.Value(); |
| @@ -820,17 +821,23 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is | |||
| 820 | std::vector<Node> coords; | 821 | std::vector<Node> coords; |
| 821 | for (std::size_t i = 0; i < type_coord_count; ++i) { | 822 | for (std::size_t i = 0; i < type_coord_count; ++i) { |
| 822 | const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1); | 823 | const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1); |
| 823 | coords.push_back(GetRegister(last ? last_coord_register : coord_register + i)); | 824 | coords.push_back( |
| 825 | GetRegister(last && !aoffi_enabled ? last_coord_register : coord_register + i)); | ||
| 824 | } | 826 | } |
| 825 | 827 | ||
| 826 | const Node array = is_array ? GetRegister(array_register) : nullptr; | 828 | const Node array = is_array ? GetRegister(array_register) : nullptr; |
| 827 | // When lod is used always is in gpr20 | 829 | // When lod is used always is in gpr20 |
| 828 | const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0); | 830 | const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0); |
| 829 | 831 | ||
| 832 | std::vector<Node> aoffi; | ||
| 833 | if (aoffi_enabled) { | ||
| 834 | aoffi = GetAoffiCoordinates(GetRegister(instr.gpr20), type_coord_count, false); | ||
| 835 | } | ||
| 836 | |||
| 830 | Node4 values; | 837 | Node4 values; |
| 831 | for (u32 element = 0; element < values.size(); ++element) { | 838 | for (u32 element = 0; element < values.size(); ++element) { |
| 832 | auto coords_copy = coords; | 839 | auto coords_copy = coords; |
| 833 | MetaTexture meta{*sampler, array, {}, {}, {}, {}, {}, lod, {}, element, {}}; | 840 | MetaTexture meta{*sampler, array, {}, aoffi, {}, {}, {}, lod, {}, element, {}}; |
| 834 | values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); | 841 | values[element] = Operation(OperationCode::TexelFetch, meta, std::move(coords_copy)); |
| 835 | } | 842 | } |
| 836 | return values; | 843 | return values; |