diff options
| -rwxr-xr-x | .ci/scripts/clang/docker.sh | 18 | ||||
| -rw-r--r-- | .ci/scripts/clang/exec.sh | 8 | ||||
| -rw-r--r-- | .ci/scripts/clang/upload.sh | 20 | ||||
| -rw-r--r-- | .ci/templates/build-standard.yml | 5 | ||||
| -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 |
7 files changed, 84 insertions, 10 deletions
diff --git a/.ci/scripts/clang/docker.sh b/.ci/scripts/clang/docker.sh new file mode 100755 index 000000000..885d74e97 --- /dev/null +++ b/.ci/scripts/clang/docker.sh | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #!/bin/bash -ex | ||
| 2 | |||
| 3 | # Exit on error, rather than continuing with the rest of the script. | ||
| 4 | set -e | ||
| 5 | |||
| 6 | cd /yuzu | ||
| 7 | |||
| 8 | ccache -s | ||
| 9 | |||
| 10 | mkdir build || true && cd build | ||
| 11 | cmake .. -DDISPLAY_VERSION=$1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/clang -DCMAKE_CXX_COMPILER=/usr/lib/ccache/clang++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DCMAKE_INSTALL_PREFIX="/usr" | ||
| 12 | |||
| 13 | make -j$(nproc) | ||
| 14 | |||
| 15 | ccache -s | ||
| 16 | |||
| 17 | ctest -VV -C Release | ||
| 18 | |||
diff --git a/.ci/scripts/clang/exec.sh b/.ci/scripts/clang/exec.sh new file mode 100644 index 000000000..e56cd4325 --- /dev/null +++ b/.ci/scripts/clang/exec.sh | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | #!/bin/bash -ex | ||
| 2 | |||
| 3 | mkdir -p "ccache" || true | ||
| 4 | chmod a+x ./.ci/scripts/clang/docker.sh | ||
| 5 | # the UID for the container yuzu user is 1027 | ||
| 6 | sudo chown -R 1027 ./ | ||
| 7 | docker run -e ENABLE_COMPATIBILITY_REPORTING -e CCACHE_DIR=/yuzu/ccache -v $(pwd):/yuzu yuzuemu/build-environments:linux-fresh /bin/bash /yuzu/.ci/scripts/clang/docker.sh $1 | ||
| 8 | sudo chown -R $UID ./ | ||
diff --git a/.ci/scripts/clang/upload.sh b/.ci/scripts/clang/upload.sh new file mode 100644 index 000000000..fe4e6b2ac --- /dev/null +++ b/.ci/scripts/clang/upload.sh | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | #!/bin/bash -ex | ||
| 2 | |||
| 3 | . .ci/scripts/common/pre-upload.sh | ||
| 4 | |||
| 5 | REV_NAME="yuzu-linux-${GITDATE}-${GITREV}" | ||
| 6 | ARCHIVE_NAME="${REV_NAME}.tar.xz" | ||
| 7 | COMPRESSION_FLAGS="-cJvf" | ||
| 8 | |||
| 9 | if [ "${RELEASE_NAME}" = "mainline" ]; then | ||
| 10 | DIR_NAME="${REV_NAME}" | ||
| 11 | else | ||
| 12 | DIR_NAME="${REV_NAME}_${RELEASE_NAME}" | ||
| 13 | fi | ||
| 14 | |||
| 15 | mkdir "$DIR_NAME" | ||
| 16 | |||
| 17 | cp build/bin/yuzu-cmd "$DIR_NAME" | ||
| 18 | cp build/bin/yuzu "$DIR_NAME" | ||
| 19 | |||
| 20 | . .ci/scripts/common/post-upload.sh | ||
diff --git a/.ci/templates/build-standard.yml b/.ci/templates/build-standard.yml index 7422c8346..57d36f813 100644 --- a/.ci/templates/build-standard.yml +++ b/.ci/templates/build-standard.yml | |||
| @@ -12,6 +12,9 @@ jobs: | |||
| 12 | windows: | 12 | windows: |
| 13 | BuildSuffix: 'windows-mingw' | 13 | BuildSuffix: 'windows-mingw' |
| 14 | ScriptFolder: 'windows' | 14 | ScriptFolder: 'windows' |
| 15 | clang: | ||
| 16 | BuildSuffix: 'clang' | ||
| 17 | ScriptFolder: 'clang' | ||
| 15 | linux: | 18 | linux: |
| 16 | BuildSuffix: 'linux' | 19 | BuildSuffix: 'linux' |
| 17 | ScriptFolder: 'linux' | 20 | ScriptFolder: 'linux' |
| @@ -24,4 +27,4 @@ jobs: | |||
| 24 | parameters: | 27 | parameters: |
| 25 | artifactSource: 'false' | 28 | artifactSource: 'false' |
| 26 | cache: $(parameters.cache) | 29 | cache: $(parameters.cache) |
| 27 | version: $(parameters.version) \ No newline at end of file | 30 | version: $(parameters.version) |
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; |