From d748dc590e73ff4472629cce974592feac5ebdca Mon Sep 17 00:00:00 2001 From: bridgewaterrobbie Date: Wed, 14 May 2025 11:05:02 -0400 Subject: [PATCH] Use WebGPU platform explicitly in shaders rather than rely on the mostly similar cases to Vulkan, with the exception of flipping the Y axis where they are different --- filament/backend/test/ShaderGenerator.cpp | 2 +- filament/backend/test/test_LoadImage.cpp | 6 +++--- libs/filamat/src/shaders/CodeGenerator.cpp | 2 -- shaders/src/common_getters.glsl | 10 +++++----- shaders/src/common_graphics.fs | 2 +- shaders/src/post_process_main.vs | 2 +- shaders/src/surface_getters.vs | 2 +- shaders/src/surface_main.vs | 2 +- 8 files changed, 13 insertions(+), 15 deletions(-) diff --git a/filament/backend/test/ShaderGenerator.cpp b/filament/backend/test/ShaderGenerator.cpp index 39bc3f9036..84f66c1ee3 100644 --- a/filament/backend/test/ShaderGenerator.cpp +++ b/filament/backend/test/ShaderGenerator.cpp @@ -118,7 +118,7 @@ ShaderGenerator::Blob ShaderGenerator::transpileShader(ShaderStage stage, std::s } else if (backend == Backend::VULKAN) { shader.insert(pos, "#define TARGET_VULKAN_ENVIRONMENT\n"); } else if (backend == Backend::WEBGPU) { - shader.insert(pos, "#define TARGET_VULKAN_ENVIRONMENT\n"); + shader.insert(pos, "#define TARGET_WEBGPU_ENVIRONMENT\n"); } const char* shaderCString = shader.c_str(); diff --git a/filament/backend/test/test_LoadImage.cpp b/filament/backend/test/test_LoadImage.cpp index a712637b26..b15ca619b6 100644 --- a/filament/backend/test/test_LoadImage.cpp +++ b/filament/backend/test/test_LoadImage.cpp @@ -52,7 +52,7 @@ layout(location = 0, set = 0) uniform {samplerType} test_tex; void main() { vec2 fbsize = vec2(512); vec2 uv = gl_FragCoord.xy / fbsize; -#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) +#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) || defined(TARGET_WEBGPU_ENVIRONMENT) uv.y = 1.0 - uv.y; #endif fragColor = vec4(texture(test_tex, uv).rgb, 1.0f); @@ -73,7 +73,7 @@ float getLayer(in sampler2DArray s) { return 2.0f; } void main() { vec2 fbsize = vec2(512); vec2 uv = gl_FragCoord.xy / fbsize; -#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) +#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) || defined(TARGET_WEBGPU_ENVIRONMENT) uv.y = 1.0 - uv.y; #endif fragColor = vec4(texture(test_tex, vec3(uv, getLayer(test_tex))).rgb, 1.0f); @@ -91,7 +91,7 @@ layout(location = 0, set = 0) uniform sampler2D test_tex; void main() { vec2 fbsize = vec2(512); vec2 uv = gl_FragCoord.xy / fbsize; -#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) +#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) || defined(TARGET_WEBGPU_ENVIRONMENT) uv.y = 1.0 - uv.y; #endif fragColor = vec4(textureLod(test_tex, uv, 1.0f).rgb, 1.0f); diff --git a/libs/filamat/src/shaders/CodeGenerator.cpp b/libs/filamat/src/shaders/CodeGenerator.cpp index 8a90365c31..5d6e1f5bd9 100644 --- a/libs/filamat/src/shaders/CodeGenerator.cpp +++ b/libs/filamat/src/shaders/CodeGenerator.cpp @@ -176,8 +176,6 @@ utils::io::sstream& CodeGenerator::generateCommonProlog(utils::io::sstream& out, // TODO: Handle webgpu here case TargetApi::WEBGPU: //For now, no differences so inherit the same changes. - // TODO Define a separte environment, OR relevant checks - out << "#define TARGET_VULKAN_ENVIRONMENT\n"; out << "#define TARGET_WEBGPU_ENVIRONMENT\n"; break; case TargetApi::ALL: diff --git a/shaders/src/common_getters.glsl b/shaders/src/common_getters.glsl index eeacab1de1..79cca65fb6 100644 --- a/shaders/src/common_getters.glsl +++ b/shaders/src/common_getters.glsl @@ -79,10 +79,10 @@ highp float getUserTimeMod(float m) { /** * Transforms a texture UV to make it suitable for a render target attachment. * - * In Vulkan and Metal, texture coords are Y-down but in OpenGL they are Y-up. This wrapper function - * accounts for these differences. When sampling from non-render targets (i.e. uploaded textures) - * these differences do not matter because OpenGL has a second piece of backwardness, which is that - * the first row of texels in glTexImage2D is interpreted as the bottom row. + * In Vulkan, WebGPU and Metal, texture coords are Y-down but in OpenGL they are Y-up. This wrapper + * function accounts for these differences. When sampling from non-render targets (i.e. uploaded + * textures) these differences do not matter because OpenGL has a second piece of backwardness, + * which is that the first row of texels in glTexImage2D is interpreted as the bottom row. * * To protect users from these differences, we recommend that materials in the SURFACE domain * leverage this wrapper function when sampling from offscreen render targets. @@ -90,7 +90,7 @@ highp float getUserTimeMod(float m) { * @public-api */ highp vec2 uvToRenderTargetUV(const highp vec2 uv) { -#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) +#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) || defined(TARGET_WEBGPU_ENVIRONMENT) return vec2(uv.x, 1.0 - uv.y); #else return uv; diff --git a/shaders/src/common_graphics.fs b/shaders/src/common_graphics.fs index 3cebbb4d55..fddfd0ccd0 100644 --- a/shaders/src/common_graphics.fs +++ b/shaders/src/common_graphics.fs @@ -95,7 +95,7 @@ vec3 decodeRGBM(vec4 c) { // returns the frag coord in the GL convention with (0, 0) at the bottom-left // resolution : width, height highp vec2 getFragCoord(const highp vec2 resolution) { -#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) +#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) || defined(TARGET_WEBGPU_ENVIRONMENT) return vec2(gl_FragCoord.x, resolution.y - gl_FragCoord.y); #else return gl_FragCoord.xy; diff --git a/shaders/src/post_process_main.vs b/shaders/src/post_process_main.vs index 6c3ddb2dea..32c33aadc1 100644 --- a/shaders/src/post_process_main.vs +++ b/shaders/src/post_process_main.vs @@ -14,7 +14,7 @@ void main() { inputs.position.z = inputs.position.z * -0.5 + 0.5; #if defined(TARGET_VULKAN_ENVIRONMENT) - // In Vulkan, clip space is Y-down. In OpenGL and Metal, clip space is Y-up. + // In Vulkan, clip space is Y-down. In OpenGL, WebGPU and Metal, clip space is Y-up. inputs.position.y = -inputs.position.y; #endif diff --git a/shaders/src/surface_getters.vs b/shaders/src/surface_getters.vs index 4d5aabba1b..0552856d73 100644 --- a/shaders/src/surface_getters.vs +++ b/shaders/src/surface_getters.vs @@ -24,7 +24,7 @@ float getObjectUserData() { #if __VERSION__ >= 300 /** @public-api */ int getVertexIndex() { -#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) +#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) || defined(TARGET_WEBGPU_ENVIRONMENT) return gl_VertexIndex; #else return gl_VertexID; diff --git a/shaders/src/surface_main.vs b/shaders/src/surface_main.vs index b957d78a85..b71d1be4af 100644 --- a/shaders/src/surface_main.vs +++ b/shaders/src/surface_main.vs @@ -8,7 +8,7 @@ void main() { #if defined(FILAMENT_HAS_FEATURE_INSTANCING) -# if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) +# if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) || defined(TARGET_WEBGPU_ENVIRONMENT) instance_index = gl_InstanceIndex; # else // PowerVR drivers don't initialize gl_InstanceID correctly if it's assigned to the varying