blob: 68874da97608a108d95db01d88008db40c2d9965 [file] [log] [blame]
// Copyright 2021 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef IREE_HAL_DRIVERS_WEBGPU_BIND_GROUP_CACHE_H_
#define IREE_HAL_DRIVERS_WEBGPU_BIND_GROUP_CACHE_H_
#include "experimental/webgpu/pipeline_layout.h"
#include "experimental/webgpu/platform/webgpu.h"
#include "iree/base/api.h"
#include "iree/hal/api.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// NOTE: this is probably too small, but this is all a hack anyway.
// TODO(benvanik): build a real cache - today this is assuming the compiler does
// a much better job than it currently does as reducing the number of push
// descriptor sets.
#define IREE_HAL_WEBGPU_BIND_GROUP_CACHE_CAPACITY 32
// A subset of WGPUBindGroupEntry containing only what we need.
// WGPUBindGroupEntry is quite large (has sampler and texture information).
typedef struct iree_hal_webgpu_bind_group_binding_t {
// TODO(benvanik): also track whether dynamic.
WGPUBufferBindingType type;
WGPUBuffer buffer;
iree_device_size_t offset;
iree_device_size_t length;
} iree_hal_webgpu_bind_group_binding_t;
typedef struct iree_hal_webgpu_bind_group_cache_entry_t {
// Group layout this bind group conforms to.
// It's possible to share bind groups with different compatible layouts but
// we don't do that yet and require an exact match.
WGPUBindGroupLayout group_layout;
// Cached WebGPU bind group containing the bindings.
WGPUBindGroup handle;
// Each bit indicates a populated binding at the respective ordinal.
iree_hal_webgpu_binding_mask_t binding_mask;
// Each source binding to use for cache equality comparison.
iree_hal_webgpu_bind_group_binding_t
bindings[IREE_HAL_WEBGPU_MAX_DESCRIPTOR_SET_BINDING_COUNT];
} iree_hal_webgpu_bind_group_cache_entry_t;
// Simple cache of WGPUBindGroups.
// Bind groups in WebGPU are immutable and we need to create new ones for each
// unique set of bindings.
typedef struct iree_hal_webgpu_bind_group_cache_t {
WGPUDevice device;
iree_host_size_t entry_count;
iree_hal_webgpu_bind_group_cache_entry_t
entries[IREE_HAL_WEBGPU_BIND_GROUP_CACHE_CAPACITY];
} iree_hal_webgpu_bind_group_cache_t;
// Initializes an empty bind group cache.
void iree_hal_webgpu_bind_group_cache_initialize(
WGPUDevice device, iree_hal_webgpu_bind_group_cache_t* out_cache);
// Deinitializes the cache and drops all bind group handles.
void iree_hal_webgpu_bind_group_cache_deinitialize(
iree_hal_webgpu_bind_group_cache_t* cache);
// Trims the cache down to its minimum size by dropping all bind groups.
// All WGPUBindGroup handles will be dropped.
void iree_hal_webgpu_bind_group_cache_trim(
iree_hal_webgpu_bind_group_cache_t* cache);
// Acquires a bind group from the cache with the given |bindings|.
// Each bit of |binding_mask| indicates a binding that is used by the caller;
// this allows for matching of cached bind groups to match any with only the
// used bindings needing to match.
// Callers may use the returned bind group handle until the cache is trimmed.
WGPUBindGroup iree_hal_webgpu_bind_group_cache_acquire(
iree_hal_webgpu_bind_group_cache_t* cache, WGPUBindGroupLayout group_layout,
const iree_hal_webgpu_bind_group_binding_t* bindings,
iree_hal_webgpu_binding_mask_t binding_mask);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // IREE_HAL_DRIVERS_WEBGPU_BIND_GROUP_CACHE_H_