Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ class RenderTargetWebGPU : public RenderTarget

protected:
RenderTargetWebGPU(wgpu::Device device,
const gpu::PlatformFeatures&,
const RenderContextWebGPUImpl::Capabilities&,
wgpu::TextureFormat framebufferFormat,
uint32_t width,
Expand All @@ -299,6 +300,7 @@ class RenderTargetWebGPU : public RenderTarget
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;
Expand Down
5 changes: 5 additions & 0 deletions renderer/src/render_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ RenderContext::RenderContext(std::unique_ptr<RenderContextImpl> impl) :
// 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);
Expand Down
125 changes: 105 additions & 20 deletions renderer/src/webgpu/render_context_webgpu_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,6 @@ constexpr static auto RIVE_FRONT_FACE = wgpu::FrontFace::CW;

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,
Expand Down Expand Up @@ -795,7 +784,7 @@ class RenderContextWebGPUImpl::ColorRampPipeline

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,
Expand Down Expand Up @@ -932,7 +921,7 @@ class RenderContextWebGPUImpl::TessellatePipeline

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,
Expand Down Expand Up @@ -1095,7 +1084,7 @@ class RenderContextWebGPUImpl::AtlasPipeline
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,
Expand Down Expand Up @@ -1878,6 +1867,15 @@ RenderContextWebGPUImpl::RenderContextWebGPUImpl(
}
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;
Expand Down Expand Up @@ -2092,6 +2090,7 @@ RenderContextWebGPUImpl::~RenderContextWebGPUImpl() {}

RenderTargetWebGPU::RenderTargetWebGPU(
wgpu::Device device,
const gpu::PlatformFeatures& platformFeatures,
const RenderContextWebGPUImpl::Capabilities& capabilities,
wgpu::TextureFormat framebufferFormat,
uint32_t width,
Expand All @@ -2100,6 +2099,7 @@ RenderTargetWebGPU::RenderTargetWebGPU(
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
Expand All @@ -2111,6 +2111,16 @@ RenderTargetWebGPU::RenderTargetWebGPU(
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
}

Expand Down Expand Up @@ -2174,7 +2184,7 @@ wgpu::TextureView RenderTargetWebGPU::msaaColorTextureView()
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,
Expand Down Expand Up @@ -2259,6 +2269,7 @@ rcp<RenderTargetWebGPU> RenderContextWebGPUImpl::makeRenderTarget(
uint32_t height)
{
return rcp(new RenderTargetWebGPU(m_device,
m_platformFeatures,
m_capabilities,
framebufferFormat,
width,
Expand Down Expand Up @@ -2992,6 +3003,71 @@ static void appendImageDrawInstanceAttribs(
});
}

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,
Expand Down Expand Up @@ -3148,17 +3224,26 @@ wgpu::RenderPipeline RenderContextWebGPUImpl::makeDrawPipeline(
}
#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,
});
Expand Down
63 changes: 48 additions & 15 deletions renderer/src/webgpu/wagyu-port/include/webgpu/webgpu_wagyu.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,22 @@ typedef struct WGPUWagyuExternalTextureImpl *WGPUWagyuExternalTexture WGPU_OBJEC
// 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
Expand Down Expand Up @@ -65,6 +66,28 @@ typedef enum WGPUWagyuShaderLanguage
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,
Expand All @@ -81,6 +104,7 @@ static const WGPUWagyuFragmentStateFeaturesFlags WGPUWagyuFragmentStateFeaturesF
// 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;
Expand Down Expand Up @@ -187,6 +211,15 @@ typedef struct WGPUWagyuDeviceDescriptor
#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;
Expand Down
1 change: 1 addition & 0 deletions tests/common/offscreen_render_target_webgpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class OffscreenRenderTargetWebGPU : public rive_tests::OffscreenRenderTarget
uint32_t width,
uint32_t height) :
RenderTargetWebGPU(impl->device(),
impl->platformFeatures(),
impl->capabilities(),
format,
width,
Expand Down
Loading
Loading