summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.ci/scripts/clang/docker.sh18
-rw-r--r--.ci/scripts/clang/exec.sh8
-rw-r--r--.ci/scripts/clang/upload.sh20
-rw-r--r--.ci/templates/build-standard.yml5
-rw-r--r--externals/glad/include/glad/glad.h3
-rw-r--r--externals/glad/src/glad.c2
-rw-r--r--src/core/hle/service/acc/acc.cpp18
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_device.h5
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp31
-rw-r--r--src/video_core/shader/decode/memory.cpp1
-rw-r--r--src/video_core/shader/decode/texture.cpp11
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.
4set -e
5
6cd /yuzu
7
8ccache -s
9
10mkdir build || true && cd build
11cmake .. -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
13make -j$(nproc)
14
15ccache -s
16
17ctest -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
3mkdir -p "ccache" || true
4chmod a+x ./.ci/scripts/clang/docker.sh
5# the UID for the container yuzu user is 1027
6sudo chown -R 1027 ./
7docker 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
8sudo 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
5REV_NAME="yuzu-linux-${GITDATE}-${GITREV}"
6ARCHIVE_NAME="${REV_NAME}.tar.xz"
7COMPRESSION_FLAGS="-cJvf"
8
9if [ "${RELEASE_NAME}" = "mainline" ]; then
10 DIR_NAME="${REV_NAME}"
11else
12 DIR_NAME="${REV_NAME}_${RELEASE_NAME}"
13fi
14
15mkdir "$DIR_NAME"
16
17cp build/bin/yuzu-cmd "$DIR_NAME"
18cp 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;
5156typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC)(GLuint index, GLdouble n, GLdouble f); 5156typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC)(GLuint index, GLdouble n, GLdouble f);
5157GLAPI PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed; 5157GLAPI PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed;
5158#define glDepthRangeIndexed glad_glDepthRangeIndexed 5158#define glDepthRangeIndexed glad_glDepthRangeIndexed
5159typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDDNVPROC)(GLuint index, GLdouble n, GLdouble f);
5160GLAPI PFNGLDEPTHRANGEINDEXEDDNVPROC glad_glDepthRangeIndexeddNV;
5161#define glDepthRangeIndexeddNV glad_glDepthRangeIndexeddNV
5159typedef void (APIENTRYP PFNGLGETFLOATI_VPROC)(GLenum target, GLuint index, GLfloat *data); 5162typedef void (APIENTRYP PFNGLGETFLOATI_VPROC)(GLenum target, GLuint index, GLfloat *data);
5160GLAPI PFNGLGETFLOATI_VPROC glad_glGetFloati_v; 5163GLAPI 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;
1044PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; 1044PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL;
1045PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL; 1045PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL;
1046PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL; 1046PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL;
1047PFNGLDEPTHRANGEINDEXEDDNVPROC glad_glDepthRangeIndexeddNV = NULL;
1047PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL; 1048PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL;
1048PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; 1049PFNGLDETACHSHADERPROC glad_glDetachShader = NULL;
1049PFNGLDISABLEPROC glad_glDisable = NULL; 1050PFNGLDISABLEPROC 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}
7975static void load_GL_NV_draw_texture(GLADloadproc load) { 7977static 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
280bool Device::TestVariableAoffi() { 282bool 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
125private: 129private:
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;