From efd202ff5cd5160ef37017bef8f1176093d25ea1 Mon Sep 17 00:00:00 2001 From: csmartdalton Date: Wed, 7 Jan 2026 22:50:26 +0000 Subject: [PATCH] chore: Move clockwiseAtomic shaders to the new system (#11388) 85c5519c6e With clockwise mode, we introduced ".vert" and ".frag" files and started sharing the main vertex shaders with multiple fragment shaders. This PR is a cleanup that removes redundant code and moves the clockwiseAtomic shaders to that same system. clockwiseAtomic shaders also work out paint colors via varyings now instead of storage buffers, which seems better but doesn't register a difference in performance. Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> --- .rive_head | 2 +- renderer/shader_hotload/shader_hotload.cpp | 6 +- renderer/src/d3d/pipeline_manager.cpp | 6 +- renderer/src/gl/render_context_gl_impl.cpp | 6 +- .../src/metal/background_shader_compiler.mm | 10 +- renderer/src/shaders/Makefile | 7 +- .../draw_clockwise_atomic_image_mesh.glsl | 69 ----- ...h.glsl => draw_clockwise_atomic_path.frag} | 258 ++---------------- ..._raster_order_mesh.frag => draw_mesh.frag} | 19 +- renderer/src/shaders/draw_path.vert | 26 +- .../metal/generate_draw_combinations.py | 4 +- .../src/shaders/spirv/draw_atlas_blit.main | 2 +- .../spirv/draw_clockwise_atlas_blit.main | 2 +- .../draw_clockwise_atomic_atlas_blit.main | 6 +- .../draw_clockwise_atomic_image_mesh.main | 5 +- ...w_clockwise_atomic_interior_triangles.main | 5 +- .../spirv/draw_clockwise_atomic_path.main | 5 +- .../spirv/draw_clockwise_image_mesh.main | 2 +- .../src/shaders/spirv/draw_image_mesh.main | 2 +- .../src/shaders/unreal/draw_image_mesh.usf | 2 +- renderer/src/vulkan/draw_pipeline_vulkan.cpp | 8 +- renderer/src/vulkan/draw_shader_vulkan.cpp | 6 +- renderer/src/vulkan/vulkan_shaders.cpp | 18 +- renderer/src/vulkan/vulkan_shaders.hpp | 6 +- .../src/webgpu/render_context_webgpu_impl.cpp | 6 +- 25 files changed, 137 insertions(+), 351 deletions(-) delete mode 100644 renderer/src/shaders/draw_clockwise_atomic_image_mesh.glsl rename renderer/src/shaders/{draw_clockwise_atomic_path.glsl => draw_clockwise_atomic_path.frag} (54%) rename renderer/src/shaders/{draw_raster_order_mesh.frag => draw_mesh.frag} (86%) diff --git a/.rive_head b/.rive_head index 22e83bab..91b702c0 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -209e1b6d961f6bc44f1e69f7e2eb6146251f66d9 +85c5519c6ec1b73ef7b9cf149084eb16779f771f diff --git a/renderer/shader_hotload/shader_hotload.cpp b/renderer/shader_hotload/shader_hotload.cpp index ef8bc2fd..c08b8331 100644 --- a/renderer/shader_hotload/shader_hotload.cpp +++ b/renderer/shader_hotload/shader_hotload.cpp @@ -126,9 +126,11 @@ rive::Span loadNewShaderFileData() riveSpirvPath / "draw_clockwise_atomic_interior_triangles.vert.spirv", riveSpirvPath / "draw_clockwise_atomic_interior_triangles.frag.spirv", riveSpirvPath / "draw_clockwise_atomic_atlas_blit.vert.spirv", - riveSpirvPath / "draw_clockwise_atomic_atlas_blit.frag.spirv", + riveSpirvPath / + "draw_clockwise_atomic_atlas_blit.fixedcolor_frag.spirv", riveSpirvPath / "draw_clockwise_atomic_image_mesh.vert.spirv", - riveSpirvPath / "draw_clockwise_atomic_image_mesh.frag.spirv", + riveSpirvPath / + "draw_clockwise_atomic_image_mesh.fixedcolor_frag.spirv", riveSpirvPath / "draw_msaa_path.vert.spirv", riveSpirvPath / "draw_msaa_path.noclipdistance_vert.spirv", diff --git a/renderer/src/d3d/pipeline_manager.cpp b/renderer/src/d3d/pipeline_manager.cpp index 11e26c8a..e21c0949 100644 --- a/renderer/src/d3d/pipeline_manager.cpp +++ b/renderer/src/d3d/pipeline_manager.cpp @@ -13,7 +13,7 @@ #include "generated/shaders/constants.glsl.hpp" #include "generated/shaders/common.glsl.hpp" #include "generated/shaders/draw_image_mesh.vert.hpp" -#include "generated/shaders/draw_raster_order_mesh.frag.hpp" +#include "generated/shaders/draw_mesh.frag.hpp" #include "generated/shaders/draw_path_common.glsl.hpp" #include "generated/shaders/draw_path.vert.hpp" #include "generated/shaders/draw_raster_order_path.frag.hpp" @@ -131,11 +131,11 @@ static std::string build_shader(DrawType drawType, case DrawType::atlasBlit: s << glsl::draw_path_common << '\n'; s << glsl::draw_path_vert << '\n'; - s << glsl::draw_raster_order_mesh_frag << '\n'; + s << glsl::draw_mesh_frag << '\n'; break; case DrawType::imageMesh: s << glsl::draw_image_mesh_vert << '\n'; - s << glsl::draw_raster_order_mesh_frag << '\n'; + s << glsl::draw_mesh_frag << '\n'; break; case DrawType::imageRect: case DrawType::renderPassResolve: diff --git a/renderer/src/gl/render_context_gl_impl.cpp b/renderer/src/gl/render_context_gl_impl.cpp index 248e3e87..c60f3a60 100644 --- a/renderer/src/gl/render_context_gl_impl.cpp +++ b/renderer/src/gl/render_context_gl_impl.cpp @@ -22,7 +22,7 @@ #include "generated/shaders/draw_clockwise_path.frag.hpp" #include "generated/shaders/draw_clockwise_clip.frag.hpp" #include "generated/shaders/draw_image_mesh.vert.hpp" -#include "generated/shaders/draw_raster_order_mesh.frag.hpp" +#include "generated/shaders/draw_mesh.frag.hpp" #include "generated/shaders/draw_msaa_object.frag.hpp" #include "generated/shaders/bezier_utils.glsl.hpp" #include "generated/shaders/tessellate.glsl.hpp" @@ -1207,11 +1207,11 @@ RenderContextGLImpl::DrawShader::DrawShader( case gpu::DrawType::atlasBlit: sources.push_back(gpu::glsl::draw_path_common); sources.push_back(gpu::glsl::draw_path_vert); - sources.push_back(gpu::glsl::draw_raster_order_mesh_frag); + sources.push_back(gpu::glsl::draw_mesh_frag); break; case gpu::DrawType::imageMesh: sources.push_back(gpu::glsl::draw_image_mesh_vert); - sources.push_back(gpu::glsl::draw_raster_order_mesh_frag); + sources.push_back(gpu::glsl::draw_mesh_frag); break; case gpu::DrawType::imageRect: case gpu::DrawType::msaaStrokes: diff --git a/renderer/src/metal/background_shader_compiler.mm b/renderer/src/metal/background_shader_compiler.mm index c216664f..cff55f8d 100644 --- a/renderer/src/metal/background_shader_compiler.mm +++ b/renderer/src/metal/background_shader_compiler.mm @@ -12,7 +12,7 @@ #include "generated/shaders/draw_path.vert.hpp" #include "generated/shaders/draw_raster_order_path.frag.hpp" #include "generated/shaders/draw_image_mesh.vert.hpp" -#include "generated/shaders/draw_raster_order_mesh.frag.hpp" +#include "generated/shaders/draw_mesh.frag.hpp" #ifndef RIVE_IOS // iOS doesn't need the atomic shaders; every non-simulated iOS device supports @@ -233,16 +233,12 @@ void BackgroundShaderCompiler::threadMain() case DrawType::atlasBlit: [source appendFormat:@"%s\n", gpu::glsl::draw_path_common]; [source appendFormat:@"%s\n", gpu::glsl::draw_path_vert]; - [source - appendFormat:@"%s\n", - gpu::glsl::draw_raster_order_mesh_frag]; + [source appendFormat:@"%s\n", gpu::glsl::draw_mesh_frag]; break; case DrawType::imageMesh: [source appendFormat:@"%s\n", gpu::glsl::draw_image_mesh_vert]; - [source - appendFormat:@"%s\n", - gpu::glsl::draw_raster_order_mesh_frag]; + [source appendFormat:@"%s\n", gpu::glsl::draw_mesh_frag]; break; case DrawType::imageRect: case DrawType::msaaStrokes: diff --git a/renderer/src/shaders/Makefile b/renderer/src/shaders/Makefile index e629f962..a1424709 100644 --- a/renderer/src/shaders/Makefile +++ b/renderer/src/shaders/Makefile @@ -170,6 +170,8 @@ SPIRV_FIXEDCOLOR_FRAG_INPUTS := \ spirv/draw_clockwise_interior_triangles_clip.main \ spirv/draw_clockwise_atlas_blit.main \ spirv/draw_clockwise_image_mesh.main \ + spirv/draw_clockwise_atomic_atlas_blit.main \ + spirv/draw_clockwise_atomic_image_mesh.main \ spirv/draw_msaa_atlas_blit.main \ spirv/draw_msaa_image_mesh.main \ spirv/draw_msaa_path.main \ @@ -188,8 +190,9 @@ spirv_out_filename_no_ext = $(OUT)/$(call spirv_typed_filename,$1,$2) spirv_type = $(lastword $(subst _, ,$2)) spirv_is_vert = $(findstring vert,$(spirv_type)) spirv_is_webgpu = $(findstring webgpu,$2) -spirv_is_atomic = $(findstring atomic,$1) -spirv_is_clockwise = $(findstring clockwise,$1) +spirv_is_not_clockwise_atomic = $(ifeq $(findstring clockwise_atomic,$1),) +spirv_is_atomic = $(and $(findstring atomic,$1),spirv_is_not_clockwise_atomic) +spirv_is_clockwise = $(and $(findstring clockwise,$1),spirv_is_not_clockwise_atomic) ## SPIR-V Optimizer settings diff --git a/renderer/src/shaders/draw_clockwise_atomic_image_mesh.glsl b/renderer/src/shaders/draw_clockwise_atomic_image_mesh.glsl deleted file mode 100644 index f5515048..00000000 --- a/renderer/src/shaders/draw_clockwise_atomic_image_mesh.glsl +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2024 Rive - */ - -#ifdef @VERTEX -ATTR_BLOCK_BEGIN(PositionAttr) -ATTR(0, float2, @a_position); -ATTR_BLOCK_END - -ATTR_BLOCK_BEGIN(UVAttr) -ATTR(1, float2, @a_texCoord); -ATTR_BLOCK_END -#endif - -VARYING_BLOCK_BEGIN -NO_PERSPECTIVE VARYING(0, float2, v_texCoord); -VARYING_BLOCK_END - -#ifdef @VERTEX -VERTEX_TEXTURE_BLOCK_BEGIN -VERTEX_TEXTURE_BLOCK_END - -IMAGE_MESH_VERTEX_MAIN(@drawVertexMain, - PositionAttr, - position, - UVAttr, - uv, - _vertexID) -{ - ATTR_UNPACK(_vertexID, position, @a_position, float2); - ATTR_UNPACK(_vertexID, uv, @a_texCoord, float2); - - VARYING_INIT(v_texCoord, float2); - - float2 vertexPosition = - MUL(make_float2x2(imageDrawUniforms.viewMatrix), @a_position) + - imageDrawUniforms.translate; - v_texCoord = @a_texCoord; - float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition); - - VARYING_PACK(v_texCoord); - EMIT_VERTEX(pos); -} -#endif - -#ifdef @FRAGMENT -FRAG_TEXTURE_BLOCK_BEGIN -TEXTURE_RGBA8(PER_DRAW_BINDINGS_SET, IMAGE_TEXTURE_IDX, @imageTexture); -FRAG_TEXTURE_BLOCK_END - -DYNAMIC_SAMPLER_BLOCK_BEGIN -SAMPLER_DYNAMIC(PER_DRAW_BINDINGS_SET, IMAGE_SAMPLER_IDX, imageSampler) -DYNAMIC_SAMPLER_BLOCK_END - -FRAG_STORAGE_BUFFER_BLOCK_BEGIN -FRAG_STORAGE_BUFFER_BLOCK_END - -FRAG_DATA_MAIN(half4, @drawFragmentMain) -{ - VARYING_UNPACK(v_texCoord, float2); - - half4 meshColor = - TEXTURE_SAMPLE_DYNAMIC(@imageTexture, imageSampler, v_texCoord); - meshColor = make_half4(unmultiply_rgb(meshColor), - meshColor.a * imageDrawUniforms.opacity); - - EMIT_FRAG_DATA(meshColor); -} -#endif // FRAGMENT diff --git a/renderer/src/shaders/draw_clockwise_atomic_path.glsl b/renderer/src/shaders/draw_clockwise_atomic_path.frag similarity index 54% rename from renderer/src/shaders/draw_clockwise_atomic_path.glsl rename to renderer/src/shaders/draw_clockwise_atomic_path.frag index 7d87ac94..6b7f4b76 100644 --- a/renderer/src/shaders/draw_clockwise_atomic_path.glsl +++ b/renderer/src/shaders/draw_clockwise_atomic_path.frag @@ -2,138 +2,8 @@ * Copyright 2023 Rive */ -#ifdef @DRAW_PATH -#ifdef @VERTEX -ATTR_BLOCK_BEGIN(Attrs) -// [localVertexID, outset, fillCoverage, vertexType] -ATTR(0, float4, @a_patchVertexData); -ATTR(1, float4, @a_mirroredVertexData); -ATTR_BLOCK_END -#endif - -VARYING_BLOCK_BEGIN -FLAT VARYING(0, ushort, v_pathID); -NO_PERSPECTIVE VARYING(1, float4, v_coverages); -NO_PERSPECTIVE VARYING(2, float2, v_atlasCoord); -FLAT VARYING(3, uint2, v_coveragePlacement); -VARYING(4, float2, v_coverageCoord); -VARYING_BLOCK_END - -#ifdef @VERTEX -VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) -{ - ATTR_UNPACK(_vertexID, attrs, @a_patchVertexData, float4); - ATTR_UNPACK(_vertexID, attrs, @a_mirroredVertexData, float4); - - VARYING_INIT(v_pathID, ushort); - VARYING_INIT(v_coverages, float4); - VARYING_INIT(v_coveragePlacement, uint2); - VARYING_INIT(v_coverageCoord, float2); - - float4 pos; - uint pathID; - float2 vertexPosition; - if (unpack_tessellated_path_vertex(@a_patchVertexData, - @a_mirroredVertexData, - _instanceID, - pathID, - vertexPosition, - v_coverages VERTEX_CONTEXT_UNPACK)) - { - uint4 coverageData = - STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 3u); - v_pathID = pathID; - v_coveragePlacement = coverageData.xy; - v_coverageCoord = vertexPosition + uintBitsToFloat(coverageData.zw); - pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition); - } - else - { - pos = float4(uniforms.vertexDiscardValue, - uniforms.vertexDiscardValue, - uniforms.vertexDiscardValue, - uniforms.vertexDiscardValue); - } - - VARYING_PACK(v_pathID); - VARYING_PACK(v_coverages); - VARYING_PACK(v_coveragePlacement); - VARYING_PACK(v_coverageCoord); - EMIT_VERTEX(pos); -} -#endif // VERTEX -#endif // DRAW_PATH - -#ifdef @DRAW_INTERIOR_TRIANGLES -#ifdef @VERTEX -ATTR_BLOCK_BEGIN(Attrs) -ATTR(0, packed_float3, @a_triangleVertex); -ATTR_BLOCK_END -#endif - -VARYING_BLOCK_BEGIN -FLAT VARYING(0, ushort, v_pathID); -#ifdef @ATLAS_BLIT -NO_PERSPECTIVE VARYING(1, float2, v_atlasCoord); -#else -@OPTIONALLY_FLAT VARYING(1, half, v_windingWeight); -FLAT VARYING(2, uint2, v_coveragePlacement); -VARYING(3, float2, v_coverageCoord); -#endif -VARYING_BLOCK_END - -#ifdef @VERTEX -VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) -{ - ATTR_UNPACK(_vertexID, attrs, @a_triangleVertex, float3); - -#ifdef @ATLAS_BLIT - VARYING_INIT(v_atlasCoord, float2); -#else -#endif - VARYING_INIT(v_pathID, ushort); -#ifdef @ATLAS_BLIT - VARYING_INIT(v_atlasCoord, float2); -#else - VARYING_INIT(v_windingWeight, half); - VARYING_INIT(v_coveragePlacement, uint2); - VARYING_INIT(v_coverageCoord, float2); -#endif - - uint pathID; - float2 vertexPosition; -#ifdef @ATLAS_BLIT - vertexPosition = - unpack_atlas_coverage_vertex(@a_triangleVertex, - pathID, - v_atlasCoord VERTEX_CONTEXT_UNPACK); -#else - vertexPosition = - unpack_interior_triangle_vertex(@a_triangleVertex, - pathID, - v_windingWeight VERTEX_CONTEXT_UNPACK); - uint4 coverageData = STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 3u); - v_coveragePlacement = coverageData.xy; - v_coverageCoord = vertexPosition + uintBitsToFloat(coverageData.zw); -#endif - v_pathID = cast_uint_to_ushort(pathID); - float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition); - - VARYING_PACK(v_pathID); -#ifdef @ATLAS_BLIT - VARYING_PACK(v_atlasCoord); -#else - VARYING_PACK(v_windingWeight); - VARYING_PACK(v_coveragePlacement); - VARYING_PACK(v_coverageCoord); -#endif - - EMIT_VERTEX(pos); -} -#endif // VERTEX -#endif // DRAW_INTERIOR_TRIANGLES - #ifdef @FRAGMENT + FRAG_STORAGE_BUFFER_BLOCK_BEGIN STORAGE_BUFFER_U32x2(PAINT_BUFFER_IDX, PaintBuffer, @paintBuffer); STORAGE_BUFFER_F32x4(PAINT_AUX_BUFFER_IDX, PaintAuxBuffer, @paintAuxBuffer); @@ -304,59 +174,31 @@ INLINE void apply_fill_coverage(INOUT(float) paintAlpha, FRAG_DATA_MAIN(half4, @drawFragmentMain) { - VARYING_UNPACK(v_pathID, ushort); -#ifdef DRAW_PATH - VARYING_UNPACK(v_coverages, float4); -#elif defined(@ATLAS_BLIT) - VARYING_UNPACK(v_atlasCoord, float2); + VARYING_UNPACK(v_paint, float4); +#ifdef @DRAW_INTERIOR_TRIANGLES + VARYING_INIT(v_windingWeight, half); #else - VARYING_UNPACK(v_windingWeight, half); + VARYING_INIT(v_coverages, COVERAGE_TYPE); +#endif //@DRAW_INTERIOR_TRIANGLES + VARYING_UNPACK(v_pathID, half); +#ifdef @ENABLE_CLIPPING + VARYING_UNPACK(v_clipIDs, half2); +#endif +#ifdef @ENABLE_CLIP_RECT + VARYING_UNPACK(v_clipRect, float4); +#endif +#ifdef @ENABLE_ADVANCED_BLEND + VARYING_UNPACK(v_blendMode, half); #endif -#ifndef @ATLAS_BLIT VARYING_UNPACK(v_coveragePlacement, uint2); VARYING_UNPACK(v_coverageCoord, float2); -#endif half4 paintColor; - uint pathID = v_pathID; - uint2 paintData = STORAGE_BUFFER_LOAD2(@paintBuffer, pathID); - uint paintType = paintData.x & 0xfu; - if (paintType <= SOLID_COLOR_PAINT_TYPE) // CLIP_UPDATE_PAINT_TYPE or - // SOLID_COLOR_PAINT_TYPE +#if defined(@DRAW_INTERIOR_TRIANGLES) && defined(@BORROWED_COVERAGE_PASS) + if (!@BORROWED_COVERAGE_PASS) +#endif { - paintColor = unpackUnorm4x8(paintData.y); - } - else // LINEAR_GRADIENT_PAINT_TYPE, - // RADIAL_GRADIENT_PAINT_TYPE, or - // IMAGE_PAINT_TYPE - { - float2x2 M = - make_float2x2(STORAGE_BUFFER_LOAD4(@paintAuxBuffer, pathID * 4u)); - float4 translate = - STORAGE_BUFFER_LOAD4(@paintAuxBuffer, pathID * 4u + 1u); - float2 paintCoord = MUL(M, _fragCoord) + translate.xy; - if (paintType != IMAGE_PAINT_TYPE) - { - float t = paintType == LINEAR_GRADIENT_PAINT_TYPE - ? /*linear*/ paintCoord.x - : /*radial*/ length(paintCoord); - t = clamp(t, .0, 1.); - float x = t * translate.z + translate.w; - float y = uintBitsToFloat(paintData.y); - paintColor = - TEXTURE_SAMPLE_LOD(@gradTexture, gradSampler, float2(x, y), .0); - } - else - { - float opacity = uintBitsToFloat(paintData.y); - float lod = translate.z; - paintColor = TEXTURE_SAMPLE_LOD(@imageTexture, - imageSampler, - paintCoord, - lod); - paintColor = - make_half4(unmultiply_rgb(paintColor), paintColor.a * opacity); - } + paintColor = find_paint_color(v_paint, 1. FRAGMENT_CONTEXT_UNPACK); } if (paintColor.a == .0) @@ -364,11 +206,13 @@ FRAG_DATA_MAIN(half4, @drawFragmentMain) discard; } -#ifdef @ATLAS_BLIT - paintColor.a *= filter_feather_atlas( - v_atlasCoord, - uniforms.atlasTextureInverseSize TEXTURE_CONTEXT_FORWARD); + half fragCoverage = +#ifdef @DRAW_INTERIOR_TRIANGLES + v_windingWeight; #else + find_frag_coverage(v_coverages); +#endif + // Swizzle the coverage buffer in a tiled format, starting with 32x32 // row-major tiles. uint coverageIndex = v_coveragePlacement.x; @@ -385,24 +229,7 @@ FRAG_DATA_MAIN(half4, @drawFragmentMain) #ifdef @BORROWED_COVERAGE_PASS if (@BORROWED_COVERAGE_PASS) { -#ifdef @DRAW_INTERIOR_TRIANGLES - half borrowedCoverage = -v_windingWeight; -#else - half fragCoverage; -#ifdef @ENABLE_FEATHER - if (@ENABLE_FEATHER && is_feathered_fill(v_coverages)) - { - fragCoverage = - eval_feathered_fill(v_coverages TEXTURE_CONTEXT_FORWARD); - } - else -#endif - { - fragCoverage = v_coverages.x; - } - half borrowedCoverage = max(-fragCoverage, .0); -#endif - apply_borrowed_coverage(borrowedCoverage, coverageIndex); + apply_borrowed_coverage(-fragCoverage, coverageIndex); discard; } #endif // BORROWED_COVERAGE_PASS @@ -410,45 +237,16 @@ FRAG_DATA_MAIN(half4, @drawFragmentMain) #ifndef @DRAW_INTERIOR_TRIANGLES if (is_stroke(v_coverages)) { - half fragCoverage; -#ifdef @ENABLE_FEATHER - if (@ENABLE_FEATHER && is_feathered_stroke(v_coverages)) - { - fragCoverage = - eval_feathered_stroke(v_coverages TEXTURE_CONTEXT_FORWARD); - } - else -#endif - { - fragCoverage = min(v_coverages.x, v_coverages.y); - } fragCoverage = clamp(fragCoverage, .0, 1.); apply_stroke_coverage(paintColor.a, fragCoverage, coverageIndex); } else // It's a fill. -#endif // !DRAW_INTERIOR_TRIANGLES +#endif // !DRAW_INTERIOR_TRIANGLES { -#ifdef @DRAW_INTERIOR_TRIANGLES - half fragCoverage = v_windingWeight; -#else - half fragCoverage; -#ifdef @ENABLE_FEATHER - if (@ENABLE_FEATHER && is_feathered_fill(v_coverages)) - { - fragCoverage = - eval_feathered_fill(v_coverages TEXTURE_CONTEXT_FORWARD); - } - else -#endif - { - fragCoverage = v_coverages.x; - } - fragCoverage = clamp(fragCoverage, .0, 1.); -#endif apply_fill_coverage(paintColor.a, fragCoverage, coverageIndex); } -#endif // @ATLAS_BLIT EMIT_FRAG_DATA(paintColor); } + #endif // FRAGMENT diff --git a/renderer/src/shaders/draw_raster_order_mesh.frag b/renderer/src/shaders/draw_mesh.frag similarity index 86% rename from renderer/src/shaders/draw_raster_order_mesh.frag rename to renderer/src/shaders/draw_mesh.frag index 1f932fb7..878b8a73 100644 --- a/renderer/src/shaders/draw_raster_order_mesh.frag +++ b/renderer/src/shaders/draw_mesh.frag @@ -4,13 +4,20 @@ #ifdef @FRAGMENT -#if defined(@FIXED_FUNCTION_COLOR_OUTPUT) && !defined(@ENABLE_CLIPPING) +// This is a basic fragment shader for non-msaa, non-path objects, e.g., image +// meshes, atlas blits. +// These objects are simple in that they can write their fragments out directly, +// without having to cooperate with overlapping fragments to work out coverage. + +#if (defined(@FIXED_FUNCTION_COLOR_OUTPUT) && !defined(@ENABLE_CLIPPING)) || \ + defined(@RENDER_MODE_CLOCKWISE_ATOMIC) // @FIXED_FUNCTION_COLOR_OUTPUT without clipping can skip the interlock. #undef NEEDS_INTERLOCK #else #define NEEDS_INTERLOCK #endif +#ifndef @RENDER_MODE_CLOCKWISE_ATOMIC PLS_BLOCK_BEGIN #ifndef @FIXED_FUNCTION_COLOR_OUTPUT PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer); @@ -21,6 +28,7 @@ PLS_DECL4F(SCRATCH_COLOR_PLANE_IDX, scratchColorBuffer); #endif PLS_DECLUI(COVERAGE_PLANE_IDX, coverageBuffer); PLS_BLOCK_END +#endif // !@RENDER_MODE_CLOCKWISE_ATOMIC // ATLAS_BLIT includes draw_path_common.glsl, which declares the textures & // samplers, so we only need to declare these for image meshes. @@ -97,7 +105,7 @@ PLS_MAIN(@drawFragmentMain) PLS_INTERLOCK_BEGIN; #endif -#ifdef @ENABLE_CLIPPING +#if defined(@ENABLE_CLIPPING) && !defined(@RENDER_MODE_CLOCKWISE_ATOMIC) if (@ENABLE_CLIPPING && v_clipID != .0) { half2 clipData = unpackHalf2x16(PLS_LOADUI(clipBuffer)); @@ -114,7 +122,8 @@ PLS_MAIN(@drawFragmentMain) coverage *= imageDrawUniforms.opacity; #endif -#ifndef @FIXED_FUNCTION_COLOR_OUTPUT +#if !defined(@FIXED_FUNCTION_COLOR_OUTPUT) && \ + !defined(@RENDER_MODE_CLOCKWISE_ATOMIC) half4 dstColorPremul = PLS_LOAD4F(colorBuffer); #ifdef @ENABLE_ADVANCED_BLEND if (@ENABLE_ADVANCED_BLEND) @@ -162,10 +171,12 @@ PLS_MAIN(@drawFragmentMain) #endif PLS_STORE4F(colorBuffer, dstColorPremul * (1. - color.a) + color); -#endif // !@FIXED_FUNCTION_COLOR_OUTPUT +#endif // !@FIXED_FUNCTION_COLOR_OUTPUT && !@RENDER_MODE_CLOCKWISE_ATOMIC +#ifndef @RENDER_MODE_CLOCKWISE_ATOMIC PLS_PRESERVE_UI(clipBuffer); PLS_PRESERVE_UI(coverageBuffer); +#endif #ifdef NEEDS_INTERLOCK PLS_INTERLOCK_END; #endif diff --git a/renderer/src/shaders/draw_path.vert b/renderer/src/shaders/draw_path.vert index ae357b09..d69f1ca4 100644 --- a/renderer/src/shaders/draw_path.vert +++ b/renderer/src/shaders/draw_path.vert @@ -5,7 +5,12 @@ // undef GENERATE_PREMULTIPLIED_PAINT_COLORS first because this file gets // included multiple times with different defines in the Metal library. #undef GENERATE_PREMULTIPLIED_PAINT_COLORS -#ifdef @ENABLE_ADVANCED_BLEND + +#ifdef @NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS +// The specific fragment shader we're being compiled for expects un-multiplied +// paint colors all the time. +#define GENERATE_PREMULTIPLIED_PAINT_COLORS false +#elif defined(@ENABLE_ADVANCED_BLEND) // If advanced blend is enabled, we generate unmultiplied paint colors in the // shader. Otherwise we would have to just turn around and unmultiply them in // order to run the blend equation. @@ -65,6 +70,12 @@ NO_PERSPECTIVE VARYING(5, float4, v_clipRect); #ifdef @ENABLE_ADVANCED_BLEND @OPTIONALLY_FLAT VARYING(6, half, v_blendMode); #endif + +#ifdef @RENDER_MODE_CLOCKWISE_ATOMIC +FLAT VARYING(7, uint2, v_coveragePlacement); +VARYING(8, float2, v_coverageCoord); +#endif + VARYING_BLOCK_END #ifdef @VERTEX @@ -103,6 +114,10 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) #ifdef @ENABLE_ADVANCED_BLEND VARYING_INIT(v_blendMode, half); #endif +#ifdef @RENDER_MODE_CLOCKWISE_ATOMIC + VARYING_INIT(v_coveragePlacement, uint2); + VARYING_INIT(v_coverageCoord, float2); +#endif bool shouldDiscardVertex = false; uint pathID; @@ -308,6 +323,11 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) #endif #ifdef @RENDER_MODE_MSAA pos.z = normalize_z_index(pathZIndex); +#elif defined(@RENDER_MODE_CLOCKWISE_ATOMIC) + uint4 coverageData = + STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 3u); + v_coveragePlacement = coverageData.xy; + v_coverageCoord = vertexPosition + uintBitsToFloat(coverageData.zw); #endif } else @@ -342,6 +362,10 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID) #endif #ifdef @ENABLE_ADVANCED_BLEND VARYING_PACK(v_blendMode); +#endif +#ifdef @RENDER_MODE_CLOCKWISE_ATOMIC + VARYING_PACK(v_coveragePlacement); + VARYING_PACK(v_coverageCoord); #endif EMIT_VERTEX(pos); } diff --git a/renderer/src/shaders/metal/generate_draw_combinations.py b/renderer/src/shaders/metal/generate_draw_combinations.py index 46a5b761..be8229ef 100644 --- a/renderer/src/shaders/metal/generate_draw_combinations.py +++ b/renderer/src/shaders/metal/generate_draw_combinations.py @@ -90,7 +90,7 @@ def emit_shader(out, shader_type, draw_type, fill_type, feature_set): out.write('{\n') out.write('#include "draw_path.minified.vert"\n') if ATLAS_BLIT in feature_set: - out.write('#include "draw_raster_order_mesh.minified.frag"\n') + out.write('#include "draw_mesh.minified.frag"\n') else: out.write('#include "draw_raster_order_path.minified.frag"\n') out.write('}\n') @@ -101,7 +101,7 @@ def emit_shader(out, shader_type, draw_type, fill_type, feature_set): out.write('namespace m%s\n' % ''.join(namespace_id)) out.write('{\n') out.write('#include "draw_image_mesh.minified.vert"\n') - out.write('#include "draw_raster_order_mesh.minified.frag"\n') + out.write('#include "draw_mesh.minified.frag"\n') out.write('}\n') out.write('#undef DRAW_IMAGE_MESH\n') out.write('#undef DRAW_IMAGE\n') diff --git a/renderer/src/shaders/spirv/draw_atlas_blit.main b/renderer/src/shaders/spirv/draw_atlas_blit.main index 499f2751..a959d341 100644 --- a/renderer/src/shaders/spirv/draw_atlas_blit.main +++ b/renderer/src/shaders/spirv/draw_atlas_blit.main @@ -10,4 +10,4 @@ #include "draw_path_common.minified.glsl" #include "advanced_blend.minified.glsl" #include "draw_path.minified.vert" -#include "draw_raster_order_mesh.minified.frag" +#include "draw_mesh.minified.frag" diff --git a/renderer/src/shaders/spirv/draw_clockwise_atlas_blit.main b/renderer/src/shaders/spirv/draw_clockwise_atlas_blit.main index 3f2be5ae..ca1a8d47 100644 --- a/renderer/src/shaders/spirv/draw_clockwise_atlas_blit.main +++ b/renderer/src/shaders/spirv/draw_clockwise_atlas_blit.main @@ -11,4 +11,4 @@ #include "draw_path_common.minified.glsl" #include "advanced_blend.minified.glsl" #include "draw_path.minified.vert" -#include "draw_raster_order_mesh.minified.frag" +#include "draw_mesh.minified.frag" diff --git a/renderer/src/shaders/spirv/draw_clockwise_atomic_atlas_blit.main b/renderer/src/shaders/spirv/draw_clockwise_atomic_atlas_blit.main index 032c63f4..f9e758c0 100644 --- a/renderer/src/shaders/spirv/draw_clockwise_atomic_atlas_blit.main +++ b/renderer/src/shaders/spirv/draw_clockwise_atomic_atlas_blit.main @@ -1,13 +1,15 @@ #version 460 #extension GL_GOOGLE_include_directive : require #extension GL_EXT_samplerless_texture_functions : require +#define ENABLE_INSTANCE_INDEX #define OPTIONALLY_FLAT flat -#define DRAW_INTERIOR_TRIANGLES #define ATLAS_BLIT +#define RENDER_MODE_CLOCKWISE_ATOMIC #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" #include "common.minified.glsl" #include "draw_path_common.minified.glsl" #include "advanced_blend.minified.glsl" -#include "draw_clockwise_atomic_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_mesh.minified.frag" diff --git a/renderer/src/shaders/spirv/draw_clockwise_atomic_image_mesh.main b/renderer/src/shaders/spirv/draw_clockwise_atomic_image_mesh.main index 77801160..841de8d2 100644 --- a/renderer/src/shaders/spirv/draw_clockwise_atomic_image_mesh.main +++ b/renderer/src/shaders/spirv/draw_clockwise_atomic_image_mesh.main @@ -4,9 +4,12 @@ #define ENABLE_INSTANCE_INDEX #define OPTIONALLY_FLAT flat #define DRAW_IMAGE +#define DRAW_IMAGE_MESH +#define RENDER_MODE_CLOCKWISE_ATOMIC #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" #include "common.minified.glsl" #include "advanced_blend.minified.glsl" -#include "draw_clockwise_atomic_image_mesh.minified.glsl" +#include "draw_image_mesh.minified.vert" +#include "draw_mesh.minified.frag" diff --git a/renderer/src/shaders/spirv/draw_clockwise_atomic_interior_triangles.main b/renderer/src/shaders/spirv/draw_clockwise_atomic_interior_triangles.main index 00802de5..cae0e4fd 100644 --- a/renderer/src/shaders/spirv/draw_clockwise_atomic_interior_triangles.main +++ b/renderer/src/shaders/spirv/draw_clockwise_atomic_interior_triangles.main @@ -3,10 +3,13 @@ #extension GL_EXT_samplerless_texture_functions : require #define OPTIONALLY_FLAT flat #define DRAW_INTERIOR_TRIANGLES +#define RENDER_MODE_CLOCKWISE_ATOMIC +#define NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" #include "common.minified.glsl" #include "draw_path_common.minified.glsl" #include "advanced_blend.minified.glsl" -#include "draw_clockwise_atomic_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_clockwise_atomic_path.minified.frag" diff --git a/renderer/src/shaders/spirv/draw_clockwise_atomic_path.main b/renderer/src/shaders/spirv/draw_clockwise_atomic_path.main index 20f9011a..78fd38a2 100644 --- a/renderer/src/shaders/spirv/draw_clockwise_atomic_path.main +++ b/renderer/src/shaders/spirv/draw_clockwise_atomic_path.main @@ -4,10 +4,13 @@ #define ENABLE_INSTANCE_INDEX #define OPTIONALLY_FLAT flat #define DRAW_PATH +#define RENDER_MODE_CLOCKWISE_ATOMIC +#define NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS #include "glsl.minified.glsl" #include "constants.minified.glsl" #include "specialization.minified.glsl" #include "common.minified.glsl" #include "draw_path_common.minified.glsl" #include "advanced_blend.minified.glsl" -#include "draw_clockwise_atomic_path.minified.glsl" +#include "draw_path.minified.vert" +#include "draw_clockwise_atomic_path.minified.frag" diff --git a/renderer/src/shaders/spirv/draw_clockwise_image_mesh.main b/renderer/src/shaders/spirv/draw_clockwise_image_mesh.main index 4452e4aa..5cf7e81f 100644 --- a/renderer/src/shaders/spirv/draw_clockwise_image_mesh.main +++ b/renderer/src/shaders/spirv/draw_clockwise_image_mesh.main @@ -10,4 +10,4 @@ #include "common.minified.glsl" #include "advanced_blend.minified.glsl" #include "draw_image_mesh.minified.vert" -#include "draw_raster_order_mesh.minified.frag" +#include "draw_mesh.minified.frag" diff --git a/renderer/src/shaders/spirv/draw_image_mesh.main b/renderer/src/shaders/spirv/draw_image_mesh.main index 4452e4aa..5cf7e81f 100644 --- a/renderer/src/shaders/spirv/draw_image_mesh.main +++ b/renderer/src/shaders/spirv/draw_image_mesh.main @@ -10,4 +10,4 @@ #include "common.minified.glsl" #include "advanced_blend.minified.glsl" #include "draw_image_mesh.minified.vert" -#include "draw_raster_order_mesh.minified.frag" +#include "draw_mesh.minified.frag" diff --git a/renderer/src/shaders/unreal/draw_image_mesh.usf b/renderer/src/shaders/unreal/draw_image_mesh.usf index 41efb220..a422cf7a 100644 --- a/renderer/src/shaders/unreal/draw_image_mesh.usf +++ b/renderer/src/shaders/unreal/draw_image_mesh.usf @@ -15,4 +15,4 @@ #include "Generated/common.minified.ush" #include "Generated/advanced_blend.minified.ush" #include "Generated/draw_image_mesh.minified.vert.ush" -#include "Generated/draw_raster_order_mesh.minified.frag.ush" +#include "Generated/draw_mesh.minified.frag.ush" diff --git a/renderer/src/vulkan/draw_pipeline_vulkan.cpp b/renderer/src/vulkan/draw_pipeline_vulkan.cpp index af1a01f1..18cf4c84 100644 --- a/renderer/src/vulkan/draw_pipeline_vulkan.cpp +++ b/renderer/src/vulkan/draw_pipeline_vulkan.cpp @@ -71,7 +71,6 @@ static VkBlendOp vk_blend_op(gpu::BlendEquation equation) { case gpu::BlendEquation::none: case gpu::BlendEquation::srcOver: - return VK_BLEND_OP_ADD; case gpu::BlendEquation::plus: return VK_BLEND_OP_ADD; case gpu::BlendEquation::max: @@ -357,7 +356,12 @@ DrawPipelineVulkan::DrawPipelineVulkan( { // Forward coverage clockwise draws are all unmultiplied src-over. blendEquation = gpu::BlendEquation::srcOver; - blendEquationPremultiplied = false; + // FIXME: clockwiseAtomic paths should be updated to use + // premultiplied alpha. + const bool isClockwiseAtomicPathDraw = + !gpu::DrawTypeIsImageDraw(props.drawType) && + props.drawType != gpu::DrawType::atlasBlit; + blendEquationPremultiplied = !isClockwiseAtomicPathDraw; } } diff --git a/renderer/src/vulkan/draw_shader_vulkan.cpp b/renderer/src/vulkan/draw_shader_vulkan.cpp index 9b8b83bd..c4c81ec2 100644 --- a/renderer/src/vulkan/draw_shader_vulkan.cpp +++ b/renderer/src/vulkan/draw_shader_vulkan.cpp @@ -239,12 +239,14 @@ DrawShaderVulkan::DrawShaderVulkan(Type type, case DrawType::atlasBlit: vertCode = spirv::draw_clockwise_atomic_atlas_blit_vert; - fragCode = spirv::draw_clockwise_atomic_atlas_blit_frag; + fragCode = + spirv::draw_clockwise_atomic_atlas_blit_fixedcolor_frag; break; case DrawType::imageMesh: vertCode = spirv::draw_clockwise_atomic_image_mesh_vert; - fragCode = spirv::draw_clockwise_atomic_image_mesh_frag; + fragCode = + spirv::draw_clockwise_atomic_image_mesh_fixedcolor_frag; break; case DrawType::imageRect: diff --git a/renderer/src/vulkan/vulkan_shaders.cpp b/renderer/src/vulkan/vulkan_shaders.cpp index d83bc368..e6b181a7 100644 --- a/renderer/src/vulkan/vulkan_shaders.cpp +++ b/renderer/src/vulkan/vulkan_shaders.cpp @@ -77,9 +77,9 @@ namespace embedded #include "generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.vert.h" #include "generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.frag.h" #include "generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.vert.h" -#include "generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.fixedcolor_frag.h" #include "generated/shaders/spirv/draw_clockwise_atomic_image_mesh.vert.h" -#include "generated/shaders/spirv/draw_clockwise_atomic_image_mesh.frag.h" +#include "generated/shaders/spirv/draw_clockwise_atomic_image_mesh.fixedcolor_frag.h" // InterlockMode::msaa shaders. #include "generated/shaders/spirv/draw_msaa_path.vert.h" @@ -228,12 +228,12 @@ rive::Span draw_clockwise_atomic_interior_triangles_frag = rive::make_span(embedded::draw_clockwise_atomic_interior_triangles_frag); rive::Span draw_clockwise_atomic_atlas_blit_vert = rive::make_span(embedded::draw_clockwise_atomic_atlas_blit_vert); -rive::Span draw_clockwise_atomic_atlas_blit_frag = - rive::make_span(embedded::draw_clockwise_atomic_atlas_blit_frag); +rive::Span draw_clockwise_atomic_atlas_blit_fixedcolor_frag = + rive::make_span(embedded::draw_clockwise_atomic_atlas_blit_fixedcolor_frag); rive::Span draw_clockwise_atomic_image_mesh_vert = rive::make_span(embedded::draw_clockwise_atomic_image_mesh_vert); -rive::Span draw_clockwise_atomic_image_mesh_frag = - rive::make_span(embedded::draw_clockwise_atomic_image_mesh_frag); +rive::Span draw_clockwise_atomic_image_mesh_fixedcolor_frag = + rive::make_span(embedded::draw_clockwise_atomic_image_mesh_fixedcolor_frag); // InterlockMode::msaa shaders. rive::Span draw_msaa_path_vert = @@ -352,9 +352,11 @@ void hotload_shaders(rive::Span spirvData) spirv::draw_clockwise_atomic_interior_triangles_frag = readNextBytecodeSpan(); spirv::draw_clockwise_atomic_atlas_blit_vert = readNextBytecodeSpan(); - spirv::draw_clockwise_atomic_atlas_blit_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_atlas_blit_fixedcolor_frag = + readNextBytecodeSpan(); spirv::draw_clockwise_atomic_image_mesh_vert = readNextBytecodeSpan(); - spirv::draw_clockwise_atomic_image_mesh_frag = readNextBytecodeSpan(); + spirv::draw_clockwise_atomic_image_mesh_fixedcolor_frag = + readNextBytecodeSpan(); spirv::draw_msaa_path_vert = readNextBytecodeSpan(); spirv::draw_msaa_path_noclipdistance_vert = readNextBytecodeSpan(); diff --git a/renderer/src/vulkan/vulkan_shaders.hpp b/renderer/src/vulkan/vulkan_shaders.hpp index de070844..906e258b 100644 --- a/renderer/src/vulkan/vulkan_shaders.hpp +++ b/renderer/src/vulkan/vulkan_shaders.hpp @@ -79,9 +79,11 @@ extern rive::Span draw_clockwise_atomic_path_frag; extern rive::Span draw_clockwise_atomic_interior_triangles_vert; extern rive::Span draw_clockwise_atomic_interior_triangles_frag; extern rive::Span draw_clockwise_atomic_atlas_blit_vert; -extern rive::Span draw_clockwise_atomic_atlas_blit_frag; +extern rive::Span + draw_clockwise_atomic_atlas_blit_fixedcolor_frag; extern rive::Span draw_clockwise_atomic_image_mesh_vert; -extern rive::Span draw_clockwise_atomic_image_mesh_frag; +extern rive::Span + draw_clockwise_atomic_image_mesh_fixedcolor_frag; // InterlockMode::msaa shaders. extern rive::Span draw_msaa_path_vert; diff --git a/renderer/src/webgpu/render_context_webgpu_impl.cpp b/renderer/src/webgpu/render_context_webgpu_impl.cpp index bfbea058..4c8a3a30 100644 --- a/renderer/src/webgpu/render_context_webgpu_impl.cpp +++ b/renderer/src/webgpu/render_context_webgpu_impl.cpp @@ -232,7 +232,7 @@ static wgpu::ShaderModule compile_shader_module_spirv(wgpu::Device device, #include "generated/shaders/draw_clockwise_path.frag.hpp" #include "generated/shaders/draw_clockwise_clip.frag.hpp" #include "generated/shaders/draw_image_mesh.vert.hpp" -#include "generated/shaders/draw_raster_order_mesh.frag.hpp" +#include "generated/shaders/draw_mesh.frag.hpp" // When compiling "glslRaw" shaders, the WebGPU driver will automatically search // for a uniform with this name and update its value when draw commands have a @@ -1054,11 +1054,11 @@ public: case DrawType::atlasBlit: glsl << gpu::glsl::draw_path_common << '\n'; glsl << gpu::glsl::draw_path_vert << '\n'; - glsl << gpu::glsl::draw_raster_order_mesh_frag << '\n'; + glsl << gpu::glsl::draw_mesh_frag << '\n'; break; case DrawType::imageMesh: glsl << gpu::glsl::draw_image_mesh_vert << '\n'; - glsl << gpu::glsl::draw_raster_order_mesh_frag << '\n'; + glsl << gpu::glsl::draw_mesh_frag << '\n'; break; case DrawType::imageRect: case DrawType::msaaStrokes: