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-- | externals/glad/include/glad/glad.h | 3 | ||||
| -rw-r--r-- | externals/glad/src/glad.c | 2 | ||||
| -rw-r--r-- | src/core/hle/service/acc/acc.cpp | 18 | ||||
| -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_rasterizer.cpp | 6 | ||||
| -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 |
13 files changed, 118 insertions, 12 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/externals/glad/include/glad/glad.h b/externals/glad/include/glad/glad.h index 6e16358ea..191bb9fcb 100644 --- a/externals/glad/include/glad/glad.h +++ b/externals/glad/include/glad/glad.h | |||
| @@ -5156,6 +5156,9 @@ GLAPI PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv; | |||
| 5156 | typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC)(GLuint index, GLdouble n, GLdouble f); | 5156 | typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC)(GLuint index, GLdouble n, GLdouble f); |
| 5157 | GLAPI PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed; | 5157 | GLAPI PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed; |
| 5158 | #define glDepthRangeIndexed glad_glDepthRangeIndexed | 5158 | #define glDepthRangeIndexed glad_glDepthRangeIndexed |
| 5159 | typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDDNVPROC)(GLuint index, GLdouble n, GLdouble f); | ||
| 5160 | GLAPI PFNGLDEPTHRANGEINDEXEDDNVPROC glad_glDepthRangeIndexeddNV; | ||
| 5161 | #define glDepthRangeIndexeddNV glad_glDepthRangeIndexeddNV | ||
| 5159 | typedef void (APIENTRYP PFNGLGETFLOATI_VPROC)(GLenum target, GLuint index, GLfloat *data); | 5162 | typedef void (APIENTRYP PFNGLGETFLOATI_VPROC)(GLenum target, GLuint index, GLfloat *data); |
| 5160 | GLAPI PFNGLGETFLOATI_VPROC glad_glGetFloati_v; | 5163 | GLAPI PFNGLGETFLOATI_VPROC glad_glGetFloati_v; |
| 5161 | #define glGetFloati_v glad_glGetFloati_v | 5164 | #define glGetFloati_v glad_glGetFloati_v |
diff --git a/externals/glad/src/glad.c b/externals/glad/src/glad.c index d3e13163f..7b24cd68d 100644 --- a/externals/glad/src/glad.c +++ b/externals/glad/src/glad.c | |||
| @@ -1044,6 +1044,7 @@ PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; | |||
| 1044 | PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; | 1044 | PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; |
| 1045 | PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL; | 1045 | PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL; |
| 1046 | PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL; | 1046 | PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL; |
| 1047 | PFNGLDEPTHRANGEINDEXEDDNVPROC glad_glDepthRangeIndexeddNV = NULL; | ||
| 1047 | PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL; | 1048 | PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL; |
| 1048 | PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; | 1049 | PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; |
| 1049 | PFNGLDISABLEPROC glad_glDisable = NULL; | 1050 | PFNGLDISABLEPROC glad_glDisable = NULL; |
| @@ -7971,6 +7972,7 @@ static void load_GL_NV_depth_buffer_float(GLADloadproc load) { | |||
| 7971 | glad_glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC)load("glDepthRangedNV"); | 7972 | glad_glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC)load("glDepthRangedNV"); |
| 7972 | glad_glClearDepthdNV = (PFNGLCLEARDEPTHDNVPROC)load("glClearDepthdNV"); | 7973 | glad_glClearDepthdNV = (PFNGLCLEARDEPTHDNVPROC)load("glClearDepthdNV"); |
| 7973 | glad_glDepthBoundsdNV = (PFNGLDEPTHBOUNDSDNVPROC)load("glDepthBoundsdNV"); | 7974 | glad_glDepthBoundsdNV = (PFNGLDEPTHBOUNDSDNVPROC)load("glDepthBoundsdNV"); |
| 7975 | glad_glDepthRangeIndexeddNV = (PFNGLDEPTHRANGEINDEXEDDNVPROC)load("glDepthRangeIndexeddNV"); | ||
| 7974 | } | 7976 | } |
| 7975 | static void load_GL_NV_draw_texture(GLADloadproc load) { | 7977 | static void load_GL_NV_draw_texture(GLADloadproc load) { |
| 7976 | if(!GLAD_GL_NV_draw_texture) return; | 7978 | if(!GLAD_GL_NV_draw_texture) return; |
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 3ec0e1eca..615e20a54 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -508,7 +508,7 @@ public: | |||
| 508 | {1, &IManagerForApplication::GetAccountId, "GetAccountId"}, | 508 | {1, &IManagerForApplication::GetAccountId, "GetAccountId"}, |
| 509 | {2, nullptr, "EnsureIdTokenCacheAsync"}, | 509 | {2, nullptr, "EnsureIdTokenCacheAsync"}, |
| 510 | {3, nullptr, "LoadIdTokenCache"}, | 510 | {3, nullptr, "LoadIdTokenCache"}, |
| 511 | {130, nullptr, "GetNintendoAccountUserResourceCacheForApplication"}, | 511 | {130, &IManagerForApplication::GetNintendoAccountUserResourceCacheForApplication, "GetNintendoAccountUserResourceCacheForApplication"}, |
| 512 | {150, nullptr, "CreateAuthorizationRequest"}, | 512 | {150, nullptr, "CreateAuthorizationRequest"}, |
| 513 | {160, &IManagerForApplication::StoreOpenContext, "StoreOpenContext"}, | 513 | {160, &IManagerForApplication::StoreOpenContext, "StoreOpenContext"}, |
| 514 | {170, nullptr, "LoadNetworkServiceLicenseKindAsync"}, | 514 | {170, nullptr, "LoadNetworkServiceLicenseKindAsync"}, |
| @@ -534,6 +534,22 @@ private: | |||
| 534 | rb.PushRaw<u64>(user_id.GetNintendoID()); | 534 | rb.PushRaw<u64>(user_id.GetNintendoID()); |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | void GetNintendoAccountUserResourceCacheForApplication(Kernel::HLERequestContext& ctx) { | ||
| 538 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | ||
| 539 | |||
| 540 | std::vector<u8> nas_user_base_for_application(0x68); | ||
| 541 | ctx.WriteBuffer(nas_user_base_for_application, 0); | ||
| 542 | |||
| 543 | if (ctx.CanWriteBuffer(1)) { | ||
| 544 | std::vector<u8> unknown_out_buffer(ctx.GetWriteBufferSize(1)); | ||
| 545 | ctx.WriteBuffer(unknown_out_buffer, 1); | ||
| 546 | } | ||
| 547 | |||
| 548 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 549 | rb.Push(RESULT_SUCCESS); | ||
| 550 | rb.PushRaw<u64>(user_id.GetNintendoID()); | ||
| 551 | } | ||
| 552 | |||
| 537 | void StoreOpenContext(Kernel::HLERequestContext& ctx) { | 553 | void StoreOpenContext(Kernel::HLERequestContext& ctx) { |
| 538 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 554 | LOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 539 | IPC::ResponseBuilder rb{ctx, 2}; | 555 | IPC::ResponseBuilder rb{ctx, 2}; |
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index 48d5c4a5e..1ae5f1d62 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp | |||
| @@ -239,6 +239,7 @@ Device::Device() { | |||
| 239 | has_nv_viewport_array2 = GLAD_GL_NV_viewport_array2; | 239 | has_nv_viewport_array2 = GLAD_GL_NV_viewport_array2; |
| 240 | has_vertex_buffer_unified_memory = GLAD_GL_NV_vertex_buffer_unified_memory; | 240 | has_vertex_buffer_unified_memory = GLAD_GL_NV_vertex_buffer_unified_memory; |
| 241 | has_debugging_tool_attached = IsDebugToolAttached(extensions); | 241 | has_debugging_tool_attached = IsDebugToolAttached(extensions); |
| 242 | has_depth_buffer_float = HasExtension(extensions, "GL_NV_depth_buffer_float"); | ||
| 242 | 243 | ||
| 243 | // At the moment of writing this, only Nvidia's driver optimizes BufferSubData on exclusive | 244 | // At the moment of writing this, only Nvidia's driver optimizes BufferSubData on exclusive |
| 244 | // uniform buffers as "push constants" | 245 | // uniform buffers as "push constants" |
| @@ -275,6 +276,7 @@ Device::Device(std::nullptr_t) { | |||
| 275 | has_image_load_formatted = true; | 276 | has_image_load_formatted = true; |
| 276 | has_texture_shadow_lod = true; | 277 | has_texture_shadow_lod = true; |
| 277 | has_variable_aoffi = true; | 278 | has_variable_aoffi = true; |
| 279 | has_depth_buffer_float = true; | ||
| 278 | } | 280 | } |
| 279 | 281 | ||
| 280 | bool Device::TestVariableAoffi() { | 282 | bool Device::TestVariableAoffi() { |
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h index ee053776d..f24bd0c7b 100644 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h | |||
| @@ -122,6 +122,10 @@ public: | |||
| 122 | return use_driver_cache; | 122 | return use_driver_cache; |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | bool HasDepthBufferFloat() const { | ||
| 126 | return has_depth_buffer_float; | ||
| 127 | } | ||
| 128 | |||
| 125 | private: | 129 | private: |
| 126 | static bool TestVariableAoffi(); | 130 | static bool TestVariableAoffi(); |
| 127 | static bool TestPreciseBug(); | 131 | static bool TestPreciseBug(); |
| @@ -150,6 +154,7 @@ private: | |||
| 150 | bool use_assembly_shaders{}; | 154 | bool use_assembly_shaders{}; |
| 151 | bool use_asynchronous_shaders{}; | 155 | bool use_asynchronous_shaders{}; |
| 152 | bool use_driver_cache{}; | 156 | bool use_driver_cache{}; |
| 157 | bool has_depth_buffer_float{}; | ||
| 153 | }; | 158 | }; |
| 154 | 159 | ||
| 155 | } // namespace OpenGL | 160 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 418644108..4610fd160 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -889,7 +889,11 @@ void RasterizerOpenGL::SyncViewport() { | |||
| 889 | const GLdouble reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne; | 889 | const GLdouble reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne; |
| 890 | const GLdouble near_depth = src.translate_z - src.scale_z * reduce_z; | 890 | const GLdouble near_depth = src.translate_z - src.scale_z * reduce_z; |
| 891 | const GLdouble far_depth = src.translate_z + src.scale_z; | 891 | const GLdouble far_depth = src.translate_z + src.scale_z; |
| 892 | glDepthRangeIndexed(static_cast<GLuint>(i), near_depth, far_depth); | 892 | if (device.HasDepthBufferFloat()) { |
| 893 | glDepthRangeIndexeddNV(static_cast<GLuint>(i), near_depth, far_depth); | ||
| 894 | } else { | ||
| 895 | glDepthRangeIndexed(static_cast<GLuint>(i), near_depth, far_depth); | ||
| 896 | } | ||
| 893 | 897 | ||
| 894 | if (!GLAD_GL_NV_viewport_swizzle) { | 898 | if (!GLAD_GL_NV_viewport_swizzle) { |
| 895 | continue; | 899 | continue; |
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; |