blob: 95549699ba68e3ecce30edbf6c0367a4d545c902 [file] [log] [blame]
/*
* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/graphite/dawn/DawnSampler.h"
#include "include/core/SkSamplingOptions.h"
#include "src/gpu/graphite/dawn/DawnCaps.h"
#include "src/gpu/graphite/dawn/DawnSharedContext.h"
#include <cfloat>
namespace skgpu::graphite {
namespace {
wgpu::FilterMode filter_mode_to_dawn_filter_mode(SkFilterMode mode) {
switch (mode) {
case SkFilterMode::kNearest:
return wgpu::FilterMode::Nearest;
case SkFilterMode::kLinear:
return wgpu::FilterMode::Linear;
}
SkUNREACHABLE;
}
wgpu::MipmapFilterMode mipmap_mode_to_dawn_filter_mode(SkMipmapMode mode) {
switch (mode) {
case SkMipmapMode::kNone:
// Dawn doesn't have none filter mode.
return wgpu::MipmapFilterMode::Nearest;
case SkMipmapMode::kNearest:
return wgpu::MipmapFilterMode::Nearest;
case SkMipmapMode::kLinear:
return wgpu::MipmapFilterMode::Linear;
}
SkUNREACHABLE;
}
}
DawnSampler::DawnSampler(const DawnSharedContext* sharedContext,
wgpu::Sampler sampler)
: Sampler(sharedContext)
, fSampler(std::move(sampler)) {}
static inline wgpu::AddressMode tile_mode_to_dawn_address_mode(SkTileMode tileMode) {
switch (tileMode) {
case SkTileMode::kClamp:
return wgpu::AddressMode::ClampToEdge;
case SkTileMode::kRepeat:
return wgpu::AddressMode::Repeat;
case SkTileMode::kMirror:
return wgpu::AddressMode::MirrorRepeat;
case SkTileMode::kDecal:
// Dawn doesn't support this mode.
return wgpu::AddressMode::ClampToEdge;
}
SkUNREACHABLE;
}
sk_sp<DawnSampler> DawnSampler::Make(const DawnSharedContext* sharedContext,
const SkSamplingOptions& samplingOptions,
SkTileMode xTileMode,
SkTileMode yTileMode) {
wgpu::SamplerDescriptor desc;
desc.addressModeU = tile_mode_to_dawn_address_mode(xTileMode);
desc.addressModeV = tile_mode_to_dawn_address_mode(yTileMode);
desc.magFilter = filter_mode_to_dawn_filter_mode(samplingOptions.filter);
desc.minFilter = desc.magFilter;
desc.mipmapFilter = mipmap_mode_to_dawn_filter_mode(samplingOptions.mipmap);
desc.lodMinClamp = 0.0f;
if (samplingOptions.mipmap == SkMipmapMode::kNone) {
// Disabling mipmap by clamping max lod to first level only.
desc.lodMaxClamp = 0.0f;
} else {
desc.lodMaxClamp = FLT_MAX;
}
desc.maxAnisotropy = 1;
desc.compare = wgpu::CompareFunction::Undefined;
std::string label;
if (sharedContext->caps()->setBackendLabels()) {
static const char* tileModeLabels[] = {"Clamp", "Repeat", "Mirror", "Decal"};
static const char* minMagFilterLabels[] = {"Nearest", "Linear"};
static const char* mipFilterLabels[] = {"MipNone", "MipNearest", "MipLinear"};
label.append("X").append(tileModeLabels[static_cast<int>(xTileMode)]);
label.append("Y").append(tileModeLabels[static_cast<int>(yTileMode)]);
label.append(minMagFilterLabels[static_cast<int>(samplingOptions.filter)]);
label.append(mipFilterLabels[static_cast<int>(samplingOptions.mipmap)]);
desc.label = label.c_str();
}
auto sampler = sharedContext->device().CreateSampler(&desc);
if (!sampler) {
return {};
}
return sk_sp<DawnSampler>(new DawnSampler(sharedContext, std::move(sampler)));
}
void DawnSampler::freeGpuData() {
fSampler = nullptr;
}
} // namespace skgpu::graphite