wagyublend
diff --git a/renderer/include/rive/renderer/webgpu/render_context_webgpu_impl.hpp b/renderer/include/rive/renderer/webgpu/render_context_webgpu_impl.hpp
index b9cb68e..94a0ce8 100644
--- a/renderer/include/rive/renderer/webgpu/render_context_webgpu_impl.hpp
+++ b/renderer/include/rive/renderer/webgpu/render_context_webgpu_impl.hpp
@@ -274,6 +274,7 @@
 
 protected:
     RenderTargetWebGPU(wgpu::Device device,
+                       const gpu::PlatformFeatures&,
                        const RenderContextWebGPUImpl::Capabilities&,
                        wgpu::TextureFormat framebufferFormat,
                        uint32_t width,
@@ -299,6 +300,7 @@
     const wgpu::Device m_device;
     const wgpu::TextureFormat m_framebufferFormat;
     wgpu::TextureUsage m_transientPLSUsage;
+    wgpu::TextureUsage m_transientMSAAUsage;
 
     wgpu::Texture m_targetTexture;
     wgpu::Texture m_coverageTexture;
diff --git a/renderer/src/render_context.cpp b/renderer/src/render_context.cpp
index f5eeca0..0c2013e 100644
--- a/renderer/src/render_context.cpp
+++ b/renderer/src/render_context.cpp
@@ -136,6 +136,11 @@
     // directly by pathID.
     m_maxPathID(MaxPathID(m_impl->platformFeatures().pathIDGranularity) - 1)
 {
+    // Validate platformFeatures: if supportsBlendAdvancedCoherentKHR is set,
+    // supportsBlendAdvancedKHR must also be.
+    assert(!m_impl->platformFeatures().supportsBlendAdvancedCoherentKHR ||
+           m_impl->platformFeatures().supportsBlendAdvancedKHR);
+
 #ifdef RIVE_GENERATE_FEATHER_LUT
     float table[GAUSSIAN_TABLE_SIZE];
     generate_gausian_integral_table(table);
diff --git a/renderer/src/webgpu/render_context_webgpu_impl.cpp b/renderer/src/webgpu/render_context_webgpu_impl.cpp
index 881c433..ed18b1f 100644
--- a/renderer/src/webgpu/render_context_webgpu_impl.cpp
+++ b/renderer/src/webgpu/render_context_webgpu_impl.cpp
@@ -112,17 +112,6 @@
 
 constexpr static uint32_t MSAA_SAMPLE_COUNT = 4u;
 
-constexpr static WGPUBlendComponent BLEND_COMPONENT_SRC_OVER = {
-    .operation = WGPUBlendOperation_Add,
-    .srcFactor = WGPUBlendFactor_One,
-    .dstFactor = WGPUBlendFactor_OneMinusSrcAlpha,
-};
-
-constexpr static WGPUBlendState BLEND_STATE_SRC_OVER = {
-    .color = BLEND_COMPONENT_SRC_OVER,
-    .alpha = BLEND_COMPONENT_SRC_OVER,
-};
-
 constexpr static WGPUStencilFaceState STENCIL_FACE_STATE_DISABLED = {
     .compare = WGPUCompareFunction_Always,
     .failOp = WGPUStencilOperation_Keep,
@@ -795,7 +784,7 @@
 
         wgpu::ShaderModule vertexShaderModule, fragmentShaderModule;
 #ifdef RIVE_WAGYU
-        if (impl->m_capabilities.backendType == wgpu::BackendType::OpenGLES)
+        if (false)
         {
             // Rive shaders tend to be long and prone to vendor bugs in the
             // compiler. Instead of wgsl, send down the raw Rive GLSL sources,
@@ -932,7 +921,7 @@
 
         wgpu::ShaderModule vertexShaderModule, fragmentShaderModule;
 #ifdef RIVE_WAGYU
-        if (impl->m_capabilities.backendType == wgpu::BackendType::OpenGLES)
+        if (false)
         {
             // Rive shaders tend to be long and prone to vendor bugs in the
             // compiler. Instead of wgsl, send down the raw Rive GLSL sources,
@@ -1095,7 +1084,7 @@
         wgpu::ShaderModule vertexShaderModule;
         wgpu::ShaderModule fillFragmentShaderModule, strokeFragmentShaderModule;
 #ifdef RIVE_WAGYU
-        if (impl->m_capabilities.backendType == wgpu::BackendType::OpenGLES)
+        if (false)
         {
             // Rive shaders tend to be long and prone to vendor bugs in the
             // compiler. Instead of wgsl, send down the raw Rive GLSL sources,
@@ -1878,6 +1867,15 @@
     }
     m_platformFeatures.atomicPLSInitNeedsDraw = true;
 
+#ifdef RIVE_WAGYU
+    // We can only use advanced blend if the client enabled it when setting up
+    // the device.
+    m_platformFeatures.supportsBlendAdvancedKHR =
+        m_platformFeatures.supportsBlendAdvancedCoherentKHR =
+            m_device.HasFeature(static_cast<wgpu::FeatureName>(
+                WGPUFeatureName_WagyuBlendEquationAdvancedCoherent));
+#endif
+
     m_platformFeatures.clipSpaceBottomUp = true;
     m_platformFeatures.framebufferBottomUp = false;
     m_platformFeatures.msaaColorPreserveNeedsDraw = true;
@@ -2092,6 +2090,7 @@
 
 RenderTargetWebGPU::RenderTargetWebGPU(
     wgpu::Device device,
+    const gpu::PlatformFeatures& platformFeatures,
     const RenderContextWebGPUImpl::Capabilities& capabilities,
     wgpu::TextureFormat framebufferFormat,
     uint32_t width,
@@ -2100,6 +2099,7 @@
     m_device(std::move(device)),
     m_framebufferFormat(framebufferFormat),
     m_transientPLSUsage(wgpu::TextureUsage::RenderAttachment),
+    m_transientMSAAUsage(wgpu::TextureUsage::RenderAttachment),
     m_targetTextureView{} // Will be configured later by setTargetTexture().
 {
 #ifdef RIVE_WAGYU
@@ -2111,6 +2111,16 @@
             WGPUTextureUsage_WagyuInputAttachment |
             WGPUTextureUsage_WagyuTransientAttachment);
     }
+    // if (platformFeatures.supportsBlendAdvancedKHR)
+    // {
+    //     // Since we support advanced blend, we don't need to interrupt MSAA
+    //     // render passes to read the framebuffer, so the MSAA buffer can be
+    //     // transient.
+    //     // IS THIS WHERE I USE WGPUTextureUsage_WagyuMSAAResolveSource TOO??
+    //     m_transientMSAAUsage |= static_cast<wgpu::TextureUsage>(
+    //         WGPUTextureUsage_WagyuTransientAttachment |
+    //         WGPUTextureUsage_WagyuMSAAResolveSource);
+    // }
 #endif
 }
 
@@ -2174,7 +2184,7 @@
     if (m_msaaColorTexture == nullptr)
     {
         wgpu::TextureDescriptor desc = {
-            .usage = wgpu::TextureUsage::RenderAttachment,
+            .usage = m_transientMSAAUsage,
             .size = {static_cast<uint32_t>(width()),
                      static_cast<uint32_t>(height())},
             .format = m_framebufferFormat,
@@ -2259,6 +2269,7 @@
     uint32_t height)
 {
     return rcp(new RenderTargetWebGPU(m_device,
+                                      m_platformFeatures,
                                       m_capabilities,
                                       framebufferFormat,
                                       width,
@@ -2992,6 +3003,71 @@
     });
 }
 
+static WGPUBlendOperation wgpuBlendOp(gpu::BlendEquation blendEquation)
+{
+    switch (blendEquation)
+    {
+        case gpu::BlendEquation::none:
+        case gpu::BlendEquation::srcOver:
+        case gpu::BlendEquation::plus:
+            return WGPUBlendOperation_Add;
+        case gpu::BlendEquation::min:
+            return WGPUBlendOperation_Min;
+        case gpu::BlendEquation::max:
+            return WGPUBlendOperation_Max;
+#ifdef RIVE_WAGYU
+        case gpu::BlendEquation::multiply:
+            return WGPUBlendOperation_WagyuMultiply;
+        case gpu::BlendEquation::screen:
+            return WGPUBlendOperation_WagyuScreen;
+        case gpu::BlendEquation::overlay:
+            return WGPUBlendOperation_WagyuOverlay;
+        case gpu::BlendEquation::darken:
+            return WGPUBlendOperation_WagyuDarken;
+        case gpu::BlendEquation::lighten:
+            return WGPUBlendOperation_WagyuLighten;
+        case gpu::BlendEquation::colorDodge:
+            return WGPUBlendOperation_WagyuColorDodge;
+        case gpu::BlendEquation::colorBurn:
+            return WGPUBlendOperation_WagyuColorBurn;
+        case gpu::BlendEquation::hardLight:
+            return WGPUBlendOperation_WagyuHardLight;
+        case gpu::BlendEquation::softLight:
+            return WGPUBlendOperation_WagyuSoftLight;
+        case gpu::BlendEquation::difference:
+            return WGPUBlendOperation_WagyuDifference;
+        case gpu::BlendEquation::exclusion:
+            return WGPUBlendOperation_WagyuExclusion;
+        case gpu::BlendEquation::hue:
+            return WGPUBlendOperation_WagyuHue;
+        case gpu::BlendEquation::saturation:
+            return WGPUBlendOperation_WagyuSaturation;
+        case gpu::BlendEquation::color:
+            return WGPUBlendOperation_WagyuColor;
+        case gpu::BlendEquation::luminosity:
+            return WGPUBlendOperation_WagyuLuminosity;
+#else
+        case gpu::BlendEquation::multiply:
+        case gpu::BlendEquation::screen:
+        case gpu::BlendEquation::overlay:
+        case gpu::BlendEquation::darken:
+        case gpu::BlendEquation::lighten:
+        case gpu::BlendEquation::colorDodge:
+        case gpu::BlendEquation::colorBurn:
+        case gpu::BlendEquation::hardLight:
+        case gpu::BlendEquation::softLight:
+        case gpu::BlendEquation::difference:
+        case gpu::BlendEquation::exclusion:
+        case gpu::BlendEquation::hue:
+        case gpu::BlendEquation::saturation:
+        case gpu::BlendEquation::color:
+        case gpu::BlendEquation::luminosity:
+            RIVE_UNREACHABLE();
+#endif
+    }
+    RIVE_UNREACHABLE();
+}
+
 wgpu::RenderPipeline RenderContextWebGPUImpl::makeDrawPipeline(
     gpu::DrawType drawType,
     gpu::ShaderFeatures shaderFeatures,
@@ -3148,17 +3224,26 @@
     }
 #endif
 
+    const WGPUBlendComponent blendComponent = {
+        .operation = wgpuBlendOp(pipelineState.blendEquation),
+        .srcFactor = WGPUBlendFactor_One,
+        .dstFactor = WGPUBlendFactor_OneMinusSrcAlpha,
+    };
+
+    const WGPUBlendState blendState = {
+        .color = blendComponent,
+        .alpha = blendComponent,
+    };
+
     StackVector<WGPUColorTargetState, PLS_PLANE_COUNT> colorAttachments;
 
     assert(colorAttachments.size() == COLOR_PLANE_IDX);
-    assert(pipelineState.blendEquation == gpu::BlendEquation::none ||
-           pipelineState.blendEquation == gpu::BlendEquation::srcOver);
     colorAttachments.push_back({
         .nextInChain = extraColorTargetState,
         .format = static_cast<WGPUTextureFormat>(framebufferFormat),
-        .blend = (pipelineState.blendEquation == gpu::BlendEquation::srcOver)
-                     ? &BLEND_STATE_SRC_OVER
-                     : nullptr,
+        .blend = (pipelineState.blendEquation == gpu::BlendEquation::none)
+                     ? nullptr
+                     : &blendState,
         .writeMask = pipelineState.colorWriteEnabled ? WGPUColorWriteMask_All
                                                      : WGPUColorWriteMask_None,
     });
diff --git a/renderer/src/webgpu/wagyu-port/include/webgpu/webgpu_wagyu.h b/renderer/src/webgpu/wagyu-port/include/webgpu/webgpu_wagyu.h
index c3e5597..9caaf93 100644
--- a/renderer/src/webgpu/wagyu-port/include/webgpu/webgpu_wagyu.h
+++ b/renderer/src/webgpu/wagyu-port/include/webgpu/webgpu_wagyu.h
@@ -22,21 +22,22 @@
 // These values extend the WGPUSType enum set from webgpu.h
 typedef enum WGPUSType_Wagyu
 {
-    WGPUSType_WagyuAdapterInfo                  = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0001,
-    WGPUSType_WagyuColorTargetState             = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0002,
-    WGPUSType_WagyuCommandEncoderDescriptor     = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0003,
-    WGPUSType_WagyuComputePipelineDescriptor    = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0004,
-    WGPUSType_WagyuDeviceDescriptor             = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0005,
-    WGPUSType_WagyuExternalTextureBindingEntry  = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0006,
-    WGPUSType_WagyuExternalTextureBindingLayout = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0007,
-    WGPUSType_WagyuFragmentState                = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0008,
-    WGPUSType_WagyuInputTextureBindingLayout    = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0009,
-    WGPUSType_WagyuRenderPassDescriptor         = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000A,
-    WGPUSType_WagyuRenderPipelineDescriptor     = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000B,
-    WGPUSType_WagyuShaderModuleDescriptor       = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000C,
-    WGPUSType_WagyuSurfaceConfiguration         = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000D,
-    WGPUSType_WagyuTextureDescriptor            = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000E,
-    WGPUSType_WagyuForce32                      = 0x7FFFFFFF
+    WGPUSType_WagyuAdapterInfo                     = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0001,
+    WGPUSType_WagyuColorTargetState                = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0002,
+    WGPUSType_WagyuCommandEncoderDescriptor        = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0003,
+    WGPUSType_WagyuComputePipelineDescriptor       = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0004,
+    WGPUSType_WagyuDeviceDescriptor                = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0005,
+    WGPUSType_WagyuExternalTextureBindingEntry     = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0006,
+    WGPUSType_WagyuExternalTextureBindingLayout    = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0007,
+    WGPUSType_WagyuFragmentState                   = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0008,
+    WGPUSType_WagyuInputTextureBindingLayout       = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0009,
+    WGPUSType_WagyuRenderPassDescriptor            = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000A,
+    WGPUSType_WagyuRenderPipelineDescriptor        = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000B,
+    WGPUSType_WagyuShaderModuleDescriptor          = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000C,
+    WGPUSType_WagyuSurfaceConfiguration            = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000D,
+    WGPUSType_WagyuTextureDescriptor               = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000E,
+    WGPUSType_WagyuDeviceWantsValidationDescriptor = WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000F,
+    WGPUSType_WagyuForce32                         = 0x7FFFFFFF
 } WGPUSType_Wagyu WGPU_ENUM_ATTRIBUTE;
 
 typedef enum WGPUWagyuDeviceFlushStatus
@@ -65,6 +66,28 @@
     WGPUWagyuShaderLanguage_Force32 = 0x7FFFFFFF
 } WGPUWagyuShaderLanguage WGPU_ENUM_ATTRIBUTE;
 
+// Wagyu-namespaced values extending upstream enums. Allocated from the reserved
+// range so they do not collide with future upstream additions.
+static const WGPUFeatureName WGPUFeatureName_WagyuBlendEquationAdvancedCoherent = (WGPUFeatureName)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0001);
+
+// Advanced blend equations (set as the WGPUBlendComponent.operation; the factors
+// are ignored). Requires the WagyuBlendEquationAdvancedCoherent feature.
+static const WGPUBlendOperation WGPUBlendOperation_WagyuMultiply   = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0001);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuScreen     = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0002);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuOverlay    = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0003);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuDarken     = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0004);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuLighten    = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0005);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuColorDodge = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0006);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuColorBurn  = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0007);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuHardLight  = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0008);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuSoftLight  = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x0009);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuDifference = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000A);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuExclusion  = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000B);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuHue        = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000C);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuSaturation = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000D);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuColor      = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000E);
+static const WGPUBlendOperation WGPUBlendOperation_WagyuLuminosity = (WGPUBlendOperation)(WGPU_WAGYU_RESERVED_RANGE_BASE + 0x000F);
+
 typedef enum WGPUWagyuWGSLFeatureType
 {
     WGPUWagyuWGSLFeatureType_Testing            = 0x00000001,
@@ -81,6 +104,7 @@
 // These values extend the WGPUTextureUsage enum set from webgpu.h
 static const WGPUTextureUsage WGPUTextureUsage_WagyuInputAttachment     = (WGPUTextureUsage)(0x0000000040000000);
 static const WGPUTextureUsage WGPUTextureUsage_WagyuTransientAttachment = (WGPUTextureUsage)(0x0000000020000000);
+static const WGPUTextureUsage WGPUTextureUsage_WagyuMSAAResolveSource   = (WGPUTextureUsage)(0x0000000080000000);
 
 // Forward declarations for callbacks
 struct WGPUWagyuDevicePipelineBinaryCacheStatistics;
@@ -187,6 +211,15 @@
 #define WGPU_WAGYU_DEVICE_DESCRIPTOR_INIT \
     WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuDeviceDescriptor, { /*.chain*/ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuDeviceDescriptor) _wgpu_COMMA /*.dataBufferNeedsDetach*/ WGPUOptionalBool_Undefined _wgpu_COMMA /*.wantsIndirectRendering*/ WGPUOptionalBool_Undefined _wgpu_COMMA /*.wantsBufferClear*/ WGPUOptionalBool_Undefined _wgpu_COMMA /*.wantsTextureClear*/ WGPUOptionalBool_Undefined _wgpu_COMMA })
 
+typedef struct WGPUWagyuDeviceWantsValidationDescriptor
+{
+    WGPUChainedStruct chain;
+    WGPUOptionalBool wantsValidation;
+} WGPUWagyuDeviceWantsValidationDescriptor WGPU_STRUCTURE_ATTRIBUTE;
+
+#define WGPU_WAGYU_DEVICE_VALIDATION_INIT \
+    WGPU_WAGYU_MAKE_INIT_STRUCT(WGPUWagyuDeviceWantsValidationDescriptor, { /*.chain*/ WGPU_WAGYU_CHAIN_INIT(WGPUSType_WagyuDeviceWantsValidationDescriptor) _wgpu_COMMA /*.wantsValidation*/ WGPUOptionalBool_Undefined _wgpu_COMMA })
+
 typedef struct WGPUWagyuDeviceFlushCallbackInfo
 {
     WGPUChainedStruct *nextInChain;
diff --git a/tests/common/offscreen_render_target_webgpu.cpp b/tests/common/offscreen_render_target_webgpu.cpp
index 2643393..8204a7d 100644
--- a/tests/common/offscreen_render_target_webgpu.cpp
+++ b/tests/common/offscreen_render_target_webgpu.cpp
@@ -58,6 +58,7 @@
                       uint32_t width,
                       uint32_t height) :
             RenderTargetWebGPU(impl->device(),
+                               impl->platformFeatures(),
                                impl->capabilities(),
                                format,
                                width,
diff --git a/tests/common/testing_window_wgpu.cpp b/tests/common/testing_window_wgpu.cpp
index de43c9f..feefd8e 100644
--- a/tests/common/testing_window_wgpu.cpp
+++ b/tests/common/testing_window_wgpu.cpp
@@ -12,7 +12,6 @@
 
 #include "common/offscreen_render_target.hpp"
 #include "rive/renderer/rive_renderer.hpp"
-#include "rive/renderer/rive_render_image.hpp"
 #include "rive/renderer/webgpu/render_context_webgpu_impl.hpp"
 
 #include <algorithm>
@@ -146,6 +145,22 @@
         }
 #endif
 
+        std::vector<wgpu::FeatureName> requiredFeatures;
+#ifdef RIVE_WAGYU
+        // Request coherent advanced blend when the adapter advertises it. This
+        // enables Rive to take the "supportsBlendAdvancedCoherentKHR" path on
+        // MSAA, and skip the framebuffer copies and renderPass interruptions
+        // for advanced blend.
+        if (m_adapter.HasFeature(static_cast<wgpu::FeatureName>(
+                WGPUFeatureName_WagyuBlendEquationAdvancedCoherent)))
+        {
+            requiredFeatures.push_back(static_cast<wgpu::FeatureName>(
+                WGPUFeatureName_WagyuBlendEquationAdvancedCoherent));
+        }
+#endif
+        deviceDesc.requiredFeatureCount = requiredFeatures.size();
+        deviceDesc.requiredFeatures = requiredFeatures.data();
+
         m_adapter.RequestDevice(
             &deviceDesc,
             wgpu::CallbackMode::AllowSpontaneous,
@@ -226,12 +241,32 @@
 
         wgpu::AdapterInfo adapterInfo;
         m_adapter.GetInfo(&adapterInfo);
-        printf("==== WGPU device: %s %s %s (%s, %s) ====\n",
+        printf("==== WGPU device: %s %s %s (%s",
                adapterInfo.vendor.data,
                adapterInfo.device.data,
                adapterInfo.description.data,
-               wgpu_backend_name(impl()->capabilities().backendType),
-               pls_impl_name(impl()->capabilities()));
+               wgpu_backend_name(impl()->capabilities().backendType));
+#ifdef RIVE_WAGYU
+        switch (impl()->capabilities().plsType)
+        {
+            case RenderContextWebGPUImpl::PixelLocalStorageType::
+                GL_EXT_shader_pixel_local_storage:
+                printf(", GL_EXT_shader_pixel_local_storage");
+                break;
+            case RenderContextWebGPUImpl::PixelLocalStorageType::
+                VK_EXT_rasterization_order_attachment_access:
+                printf(", VK_EXT_rasterization_order_attachment_access");
+                break;
+            case RenderContextWebGPUImpl::PixelLocalStorageType::none:
+                break;
+        }
+#endif
+        if (m_renderContext->platformFeatures()
+                .supportsBlendAdvancedCoherentKHR)
+        {
+            printf(", WagyuBlendEquationAdvancedCoherent");
+        }
+        printf(") ====\n");
     }
 
     rive::Factory* factory() override { return m_renderContext.get(); }