Skip to content

Commit

Permalink
[WebGPU] Sampler states across all argument buffers are unbounded
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=275294
<radar://129227428>

Reviewed by Dan Glastonbury.

The max number of unique samplers allowed per process is -[MTLDevice maxArgumentBufferSamplerCount]
which is currently 96 on most iOS devices and 1024 on many macOS devices.

We need to ensure if we create more than the limit, we dealloc one so only samplers up to the
limit are created.

This doesn't interfer with WebGL as it only applies to samplers created with supportArgumentBuffers = YES.

We can not easily set this flag to NO without avoiding ICBs which would come with substantial performance cost.

* LayoutTests/fast/webgpu/nocrash/fuzz-275294-expected.txt: Added.
* LayoutTests/fast/webgpu/nocrash/fuzz-275294.html: Added.
Add regression test.

* Source/WebCore/Modules/WebGPU/Implementation/WebGPUDeviceImpl.cpp:
(WebCore::WebGPU::DeviceImpl::createSampler):
* Source/WebGPU/WebGPU.xcodeproj/project.pbxproj:
* Source/WebGPU/WebGPU/BindGroup.h:
(WebGPU::BindGroup::create):
* Source/WebGPU/WebGPU/BindGroup.mm:
(WebGPU::Device::createBindGroup):
(WebGPU::BindGroup::BindGroup):
(WebGPU::BindGroup::rebindSamplersIfNeeded const):
* Source/WebGPU/WebGPU/BindGroupLayout.h:
* Source/WebGPU/WebGPU/ComputePassEncoder.mm:
(WebGPU::ComputePassEncoder::executePreDispatchCommands):
* Source/WebGPU/WebGPU/RenderPassEncoder.mm:
(WebGPU::RenderPassEncoder::executePreDrawCommands):
* Source/WebGPU/WebGPU/Sampler.h:
(WebGPU::Sampler::create):
(WebGPU::Sampler::isValid const): Deleted.
(WebGPU::Sampler::samplerState const): Deleted.
* Source/WebGPU/WebGPU/Sampler.mm:
(-[SamplerIdentifier initWithFirst:second:]):
(-[SamplerIdentifier copyWithZone:]):
(WebGPU::miscHash):
(WebGPU::floatToUint64):
(WebGPU::computeDescriptorHash):
(WebGPU::createMetalDescriptorFromDescriptor):
(WebGPU::Device::createSampler):
(WebGPU::Sampler::Sampler):
(WebGPU::Sampler::setLabel):
(WebGPU::Sampler::isValid const):
(WebGPU::Sampler::samplerState const):
(WebGPU::Sampler::cachedSampler const):
* Source/WebGPU/WebGPU/ShaderStage.h: Added.
* Source/WebGPU/WebGPU/WebGPU.h:

Canonical link: https://commits.webkit.org/279893@main
  • Loading branch information
mwyrzykowski committed Jun 11, 2024
1 parent a2ce771 commit 52423d2
Show file tree
Hide file tree
Showing 13 changed files with 4,391 additions and 56 deletions.
10 changes: 10 additions & 0 deletions LayoutTests/fast/webgpu/nocrash/fuzz-275294-expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 1,10 @@
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600 [color=#99DDBBCC] [bgcolor=#102030E0]
RenderBody {BODY} at (8,8) size 784x584
RenderImage {IMG} at (0,414) size 21x128
layer at (29,8) size 748x542
RenderHTMLCanvas {CANVAS} at (21,0) size 748x542
layer at (8,550) size 16x16
RenderVideo {VIDEO} at (0,542) size 16x16
4,127 changes: 4,127 additions & 0 deletions LayoutTests/fast/webgpu/nocrash/fuzz-275294.html

Large diffs are not rendered by default.

26 changes: 12 additions & 14 deletions Source/WebCore/Modules/WebGPU/Implementation/WebGPUDeviceImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,21 137,19 @@ RefPtr<Texture> DeviceImpl::createTexture(const TextureDescriptor& descriptor)

RefPtr<Sampler> DeviceImpl::createSampler(const SamplerDescriptor& descriptor)
{
auto label = descriptor.label.utf8();

WGPUSamplerDescriptor backingDescriptor {
nullptr,
label.data(),
m_convertToBackingContext->convertToBacking(descriptor.addressModeU),
m_convertToBackingContext->convertToBacking(descriptor.addressModeV),
m_convertToBackingContext->convertToBacking(descriptor.addressModeW),
m_convertToBackingContext->convertToBacking(descriptor.magFilter),
m_convertToBackingContext->convertToBacking(descriptor.minFilter),
m_convertToBackingContext->convertToBacking(descriptor.mipmapFilter),
descriptor.lodMinClamp,
descriptor.lodMaxClamp,
descriptor.compare ? m_convertToBackingContext->convertToBacking(*descriptor.compare) : WGPUCompareFunction_Undefined,
descriptor.maxAnisotropy,
.nextInChain = nullptr,
.label = descriptor.label,
.addressModeU = m_convertToBackingContext->convertToBacking(descriptor.addressModeU),
.addressModeV = m_convertToBackingContext->convertToBacking(descriptor.addressModeV),
.addressModeW = m_convertToBackingContext->convertToBacking(descriptor.addressModeW),
.magFilter = m_convertToBackingContext->convertToBacking(descriptor.magFilter),
.minFilter = m_convertToBackingContext->convertToBacking(descriptor.minFilter),
.mipmapFilter = m_convertToBackingContext->convertToBacking(descriptor.mipmapFilter),
.lodMinClamp = descriptor.lodMinClamp,
.lodMaxClamp = descriptor.lodMaxClamp,
.compare = descriptor.compare ? m_convertToBackingContext->convertToBacking(*descriptor.compare) : WGPUCompareFunction_Undefined,
.maxAnisotropy = descriptor.maxAnisotropy,
};

return SamplerImpl::create(adoptWebGPU(wgpuDeviceCreateSampler(m_backing.get(), &backingDescriptor)), m_convertToBackingContext);
Expand Down
4 changes: 4 additions & 0 deletions Source/WebGPU/WebGPU.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 12,7 @@
0D30F93929F1FAC50055D9F1 /* ExternalTexture.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D30F93829F1FAC50055D9F1 /* ExternalTexture.h */; };
0D30F93B29F1FBE40055D9F1 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D30F93A29F1FBE40055D9F1 /* CoreVideo.framework */; };
0D509DCD29CAB6EC00546D84 /* MetalSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D509DCC29CAB6EC00546D84 /* MetalSPI.h */; };
0DE2BFAD2C150DF700D04AEB /* ShaderStage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0DE2BFAC2C150DF700D04AEB /* ShaderStage.h */; };
1C0F41EE280940650005886D /* HardwareCapabilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C0F41EC280940650005886D /* HardwareCapabilities.mm */; };
1C2CEDEE271E8A7300EDC16F /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C2CEDED271E8A7300EDC16F /* Metal.framework */; };
1C582FF927E04131009B40F0 /* CommandsMixin.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C582FF727E04131009B40F0 /* CommandsMixin.mm */; };
Expand Down Expand Up @@ -267,6 268,7 @@
0D30F93A29F1FBE40055D9F1 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
0D4D2E80294A89CF0000A1AB /* BindableResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BindableResource.h; sourceTree = "<group>"; };
0D509DCC29CAB6EC00546D84 /* MetalSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MetalSPI.h; sourceTree = "<group>"; };
0DE2BFAC2C150DF700D04AEB /* ShaderStage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShaderStage.h; sourceTree = "<group>"; };
1C0F41EC280940650005886D /* HardwareCapabilities.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = HardwareCapabilities.mm; sourceTree = "<group>"; };
1C0F41ED280940650005886D /* HardwareCapabilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HardwareCapabilities.h; sourceTree = "<group>"; };
1C2CEDED271E8A7300EDC16F /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -619,6 621,7 @@
1C5ACAE8273A55FD0095F8D5 /* Sampler.mm */,
1CEBD80D2716C3D800A5254D /* ShaderModule.h */,
1C5ACAB0273A426D0095F8D5 /* ShaderModule.mm */,
0DE2BFAC2C150DF700D04AEB /* ShaderStage.h */,
1C5ACA99273A426D0095F8D5 /* Texture.h */,
1C5ACAB1273A426D0095F8D5 /* Texture.mm */,
1C5ACADD273A4F3D0095F8D5 /* TextureView.h */,
Expand Down Expand Up @@ -843,6 846,7 @@
0D30F93929F1FAC50055D9F1 /* ExternalTexture.h in Headers */,
0D509DCD29CAB6EC00546D84 /* MetalSPI.h in Headers */,
973F784729C8A78200166C66 /* Pipeline.h in Headers */,
0DE2BFAD2C150DF700D04AEB /* ShaderStage.h in Headers */,
1C5ACAD3273A4C860095F8D5 /* WebGPUExt.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
12 changes: 9 additions & 3 deletions Source/WebGPU/WebGPU/BindGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 26,7 @@
#pragma once

#import "BindableResource.h"
#import "ShaderStage.h"
#import <wtf/FastMalloc.h>
#import <wtf/Ref.h>
#import <wtf/RefCounted.h>
Expand All @@ -45,6 46,9 @@ class Sampler;
class BindGroup : public WGPUBindGroupImpl, public RefCounted<BindGroup>, public CanMakeWeakPtr<BindGroup> {
WTF_MAKE_FAST_ALLOCATED;
public:
template <typename T>
using ShaderStageArray = EnumeratedArray<ShaderStage, T, ShaderStage::Compute>;
using SamplersContainer = HashMap<RefPtr<Sampler>, ShaderStageArray<std::optional<uint32_t>>>;
struct BufferAndType {
WGPUBufferBindingType type;
uint64_t bindingSize;
Expand All @@ -55,7 59,7 @@ class BindGroup : public WGPUBindGroupImpl, public RefCounted<BindGroup>, public

static constexpr MTLRenderStages MTLRenderStageCompute = static_cast<MTLRenderStages>(0);
static constexpr MTLRenderStages MTLRenderStageUndefined = static_cast<MTLRenderStages>(MTLRenderStageFragment 1);
static Ref<BindGroup> create(id<MTLBuffer> vertexArgumentBuffer, id<MTLBuffer> fragmentArgumentBuffer, id<MTLBuffer> computeArgumentBuffer, Vector<BindableResources>&& resources, const BindGroupLayout& bindGroupLayout, DynamicBuffersContainer&& dynamicBuffers, HashSet<RefPtr<Sampler>>&& samplers, Device& device)
static Ref<BindGroup> create(id<MTLBuffer> vertexArgumentBuffer, id<MTLBuffer> fragmentArgumentBuffer, id<MTLBuffer> computeArgumentBuffer, Vector<BindableResources>&& resources, const BindGroupLayout& bindGroupLayout, DynamicBuffersContainer&& dynamicBuffers, SamplersContainer&& samplers, Device& device)
{
return adoptRef(*new BindGroup(vertexArgumentBuffer, fragmentArgumentBuffer, computeArgumentBuffer, WTFMove(resources), bindGroupLayout, WTFMove(dynamicBuffers), WTFMove(samplers), device));
}
Expand Down Expand Up @@ -84,8 88,10 @@ class BindGroup : public WGPUBindGroupImpl, public RefCounted<BindGroup>, public
const BindGroupLayout* bindGroupLayout() const;
const BufferAndType* dynamicBuffer(uint32_t) const;
uint32_t dynamicOffset(uint32_t bindingIndex, const Vector<uint32_t>*) const;
void rebindSamplersIfNeeded() const;

private:
BindGroup(id<MTLBuffer> vertexArgumentBuffer, id<MTLBuffer> fragmentArgumentBuffer, id<MTLBuffer> computeArgumentBuffer, Vector<BindableResources>&&, const BindGroupLayout&, DynamicBuffersContainer&&, HashSet<RefPtr<Sampler>>&&, Device&);
BindGroup(id<MTLBuffer> vertexArgumentBuffer, id<MTLBuffer> fragmentArgumentBuffer, id<MTLBuffer> computeArgumentBuffer, Vector<BindableResources>&&, const BindGroupLayout&, DynamicBuffersContainer&&, SamplersContainer&&, Device&);
BindGroup(Device&);

const id<MTLBuffer> m_vertexArgumentBuffer { nil };
Expand All @@ -97,7 103,7 @@ class BindGroup : public WGPUBindGroupImpl, public RefCounted<BindGroup>, public
RefPtr<const BindGroupLayout> m_bindGroupLayout;
DynamicBuffersContainer m_dynamicBuffers;
HashMap<uint32_t, uint32_t, DefaultHash<uint32_t>, WTF::UnsignedWithZeroKeyHashTraits<uint32_t>> m_dynamicOffsetsIndices;
HashSet<RefPtr<Sampler>> m_samplers;
SamplersContainer m_samplers;
};

} // namespace WebGPU
38 changes: 30 additions & 8 deletions Source/WebGPU/WebGPU/BindGroup.mm
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 77,6 @@ static MTLRenderStages metalRenderStage(ShaderStage shaderStage)
}
}

template <typename T>
using ShaderStageArray = EnumeratedArray<ShaderStage, T, ShaderStage::Compute>;

#if HAVE(COREVIDEO_METAL_SUPPORT)

enum class TransferFunctionCV {
Expand Down Expand Up @@ -902,8 899,8 @@ static BindGroupEntryUsageData makeBindGroupEntryUsageData(BindGroupEntryUsage u
return BindGroup::createInvalid(*this);
}

ShaderStageArray<id<MTLArgumentEncoder>> argumentEncoder = std::array<id<MTLArgumentEncoder>, stageCount>({ bindGroupLayout.vertexArgumentEncoder(), bindGroupLayout.fragmentArgumentEncoder(), bindGroupLayout.computeArgumentEncoder() });
ShaderStageArray<id<MTLBuffer>> argumentBuffer;
BindGroup::ShaderStageArray<id<MTLArgumentEncoder>> argumentEncoder = std::array<id<MTLArgumentEncoder>, stageCount>({ bindGroupLayout.vertexArgumentEncoder(), bindGroupLayout.fragmentArgumentEncoder(), bindGroupLayout.computeArgumentEncoder() });
BindGroup::ShaderStageArray<id<MTLBuffer>> argumentBuffer;
for (ShaderStage stage : stages) {
auto encodedLength = bindGroupLayout.encodedLength(stage);
argumentBuffer[stage] = encodedLength ? safeCreateBuffer(encodedLength, MTLStorageModeShared) : nil;
Expand All @@ -920,7 917,7 @@ static BindGroupEntryUsageData makeBindGroupEntryUsageData(BindGroupEntryUsage u
return a.binding < b.binding;
});
BindGroup::DynamicBuffersContainer dynamicBuffers;
HashSet<RefPtr<Sampler>> samplersSet;
BindGroup::SamplersContainer samplersSet;

for (uint32_t i = 0, entryCount = descriptor.entryCount; i < entryCount; i) {
const WGPUBindGroupEntry& entry = descriptor.entries[i];
Expand Down Expand Up @@ -1046,7 1043,7 @@ static BindGroupEntryUsageData makeBindGroupEntryUsageData(BindGroupEntryUsage u
id<MTLSamplerState> sampler = apiSampler.samplerState();
if (stage != ShaderStage::Undefined) {
[argumentEncoder[stage] setSamplerState:sampler atIndex:index];
samplersSet.add(&apiSampler);
samplersSet.add(&apiSampler, BindGroup::ShaderStageArray<std::optional<uint32_t>> { }).iterator->value[stage] = index;
}
} else if (textureViewIsPresent) {
auto it = bindGroupLayoutEntries.find(bindingIndex);
Expand Down Expand Up @@ -1184,7 1181,7 @@ static BindGroupEntryUsageData makeBindGroupEntryUsageData(BindGroupEntryUsage u
return m_bindGroupLayout.get();
}

BindGroup::BindGroup(id<MTLBuffer> vertexArgumentBuffer, id<MTLBuffer> fragmentArgumentBuffer, id<MTLBuffer> computeArgumentBuffer, Vector<BindableResources>&& resources, const BindGroupLayout& bindGroupLayout, DynamicBuffersContainer&& dynamicBuffers, HashSet<RefPtr<Sampler>>&& samplers, Device& device)
BindGroup::BindGroup(id<MTLBuffer> vertexArgumentBuffer, id<MTLBuffer> fragmentArgumentBuffer, id<MTLBuffer> computeArgumentBuffer, Vector<BindableResources>&& resources, const BindGroupLayout& bindGroupLayout, DynamicBuffersContainer&& dynamicBuffers, SamplersContainer&& samplers, Device& device)
: m_vertexArgumentBuffer(vertexArgumentBuffer)
, m_fragmentArgumentBuffer(fragmentArgumentBuffer)
, m_computeArgumentBuffer(computeArgumentBuffer)
Expand Down Expand Up @@ -1277,6 1274,31 @@ static BindGroupEntryUsageData makeBindGroupEntryUsageData(BindGroupEntryUsage u
return (static_cast<uint64_t>(aspect) - 1) | (static_cast<uint64_t>(baseMipLevel) << 1) | (static_cast<uint64_t>(baseArrayLayer) << 32);
}

void BindGroup::rebindSamplersIfNeeded() const
{
for (auto& [samplerRefPtr, shaderStageArray] : m_samplers) {
auto* sampler = samplerRefPtr.get();
ASSERT(sampler);
if (!sampler || sampler->cachedSampler())
continue;

WTFLogAlways("Rebinding of samplers required, if this occurs frequently the application is using too many unique samplers");
id<MTLSamplerState> samplerState = sampler->samplerState();
if (shaderStageArray[ShaderStage::Vertex].has_value()) {
[m_bindGroupLayout->vertexArgumentEncoder() setArgumentBuffer:vertexArgumentBuffer() offset:0];
[m_bindGroupLayout->vertexArgumentEncoder() setSamplerState:samplerState atIndex:*shaderStageArray[ShaderStage::Vertex]];
}
if (shaderStageArray[ShaderStage::Fragment].has_value()) {
[m_bindGroupLayout->fragmentArgumentEncoder() setArgumentBuffer:fragmentArgumentBuffer() offset:0];
[m_bindGroupLayout->fragmentArgumentEncoder() setSamplerState:samplerState atIndex:*shaderStageArray[ShaderStage::Fragment]];
}
if (shaderStageArray[ShaderStage::Compute].has_value()) {
[m_bindGroupLayout->computeArgumentEncoder() setArgumentBuffer:computeArgumentBuffer() offset:0];
[m_bindGroupLayout->computeArgumentEncoder() setSamplerState:samplerState atIndex:*shaderStageArray[ShaderStage::Compute]];
}
}
}

} // namespace WebGPU

#pragma mark WGPU Stubs
Expand Down
8 changes: 1 addition & 7 deletions Source/WebGPU/WebGPU/BindGroupLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 25,7 @@

#pragma once

#import "ShaderStage.h"
#import <wtf/EnumeratedArray.h>
#import <wtf/FastMalloc.h>
#import <wtf/HashMap.h>
Expand All @@ -39,13 40,6 @@ struct WGPUBindGroupLayoutImpl {

namespace WebGPU {

enum class ShaderStage {
Vertex = 0,
Fragment = 1,
Compute = 2,
Undefined = 3
};

class BindGroup;
class Device;
class PipelineLayout;
Expand Down
1 change: 1 addition & 0 deletions Source/WebGPU/WebGPU/ComputePassEncoder.mm
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 179,7 @@ static bool addResourceToActiveResources(const BindGroupEntryUsageData::Resource
return;
}
auto& group = *kvp.value.get();
group.rebindSamplersIfNeeded();
const Vector<uint32_t>* dynamicOffsets = nullptr;
if (auto it = m_bindGroupDynamicOffsets.find(bindGroupIndex); it != m_bindGroupDynamicOffsets.end())
dynamicOffsets = &it->value;
Expand Down
1 change: 1 addition & 0 deletions Source/WebGPU/WebGPU/RenderPassEncoder.mm
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 499,7 @@ static void setViewportMinMaxDepthIntoBuffer(auto& fragmentDynamicOffsets, float
return false;
}
auto& group = *weakBindGroup.get();
group.rebindSamplersIfNeeded();
const Vector<uint32_t>* dynamicOffsets = nullptr;
if (auto it = m_bindGroupDynamicOffsets.find(groupIndex); it != m_bindGroupDynamicOffsets.end())
dynamicOffsets = &it->value;
Expand Down
29 changes: 21 additions & 8 deletions Source/WebGPU/WebGPU/Sampler.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 32,14 @@
struct WGPUSamplerImpl {
};

@interface SamplerIdentifier : NSObject<NSCopying>
- (instancetype)initWithFirst:(uint64_t)first second:(uint64_t)second NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;

@property (nonatomic) uint64_t first;
@property (nonatomic) uint64_t second;
@end

namespace WebGPU {

class Device;
Expand All @@ -40,9 48,9 @@ class Device;
class Sampler : public WGPUSamplerImpl, public RefCounted<Sampler> {
WTF_MAKE_FAST_ALLOCATED;
public:
static Ref<Sampler> create(id<MTLSamplerState> samplerState, const WGPUSamplerDescriptor& descriptor, Device& device)
static Ref<Sampler> create(SamplerIdentifier* samplerIdentifier, const WGPUSamplerDescriptor& descriptor, Device& device)
{
return adoptRef(*new Sampler(samplerState, descriptor, device));
return adoptRef(*new Sampler(samplerIdentifier, descriptor, device));
}
static Ref<Sampler> createInvalid(Device& device)
{
Expand All @@ -53,24 61,29 @@ class Sampler : public WGPUSamplerImpl, public RefCounted<Sampler> {

void setLabel(String&&);

bool isValid() const { return m_samplerState; }
bool isValid() const;

id<MTLSamplerState> samplerState() const { return m_samplerState; }
id<MTLSamplerState> cachedSampler() const;
id<MTLSamplerState> samplerState() const;
const WGPUSamplerDescriptor& descriptor() const { return m_descriptor; }
bool isComparison() const { return descriptor().compare != WGPUCompareFunction_Undefined; }
bool isFiltering() const { return descriptor().minFilter == WGPUFilterMode_Linear || descriptor().magFilter == WGPUFilterMode_Linear || descriptor().mipmapFilter == WGPUMipmapFilterMode_Linear; }

Device& device() const { return m_device; }

private:
Sampler(id<MTLSamplerState>, const WGPUSamplerDescriptor&, Device&);
Sampler(SamplerIdentifier*, const WGPUSamplerDescriptor&, Device&);
Sampler(Device&);

const id<MTLSamplerState> m_samplerState { nil };

const WGPUSamplerDescriptor m_descriptor { };
SamplerIdentifier* m_samplerIdentifier { nil };
WGPUSamplerDescriptor m_descriptor { };

const Ref<Device> m_device;
// static is intentional here as the limit is per process
static NSMutableDictionary<SamplerIdentifier*, id<MTLSamplerState>> *cachedSamplerStates;
static NSMutableOrderedSet<SamplerIdentifier*> *lastAccessedKeys;

mutable __weak id<MTLSamplerState> m_cachedSamplerState { nil };
};

} // namespace WebGPU
Loading

0 comments on commit 52423d2

Please sign in to comment.