blob: b5f180e3197704ba1d74084d7fb69e79ea6ff4fd [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/DawnTexture.h"
#include "include/gpu/graphite/dawn/DawnTypes.h"
#include "include/private/gpu/graphite/DawnTypesPriv.h"
#include "src/core/SkMipmap.h"
#include "src/gpu/MutableTextureStateRef.h"
#include "src/gpu/graphite/Log.h"
#include "src/gpu/graphite/dawn/DawnCaps.h"
#include "src/gpu/graphite/dawn/DawnGraphiteUtilsPriv.h"
#include "src/gpu/graphite/dawn/DawnSharedContext.h"
namespace skgpu::graphite {
namespace {
const char* texture_info_to_label(const TextureInfo& info,
const DawnTextureSpec& dawnSpec) {
#ifdef SK_DEBUG
if (dawnSpec.fUsage & wgpu::TextureUsage::RenderAttachment) {
if (DawnFormatIsDepthOrStencil(dawnSpec.fFormat)) {
return "DepthStencil";
} else {
if (info.numSamples() > 1) {
if (dawnSpec.fUsage & wgpu::TextureUsage::TextureBinding) {
return "MSAA SampledTexture-ColorAttachment";
} else {
return "MSAA ColorAttachment";
}
} else {
if (dawnSpec.fUsage & wgpu::TextureUsage::TextureBinding) {
return "SampledTexture-ColorAttachment";
} else {
return "ColorAttachment";
}
}
}
} else {
SkASSERT(dawnSpec.fUsage & wgpu::TextureUsage::TextureBinding);
return "SampledTexture";
}
#else
return nullptr;
#endif
}
}
wgpu::Texture DawnTexture::MakeDawnTexture(const DawnSharedContext* sharedContext,
SkISize dimensions,
const TextureInfo& info) {
const Caps* caps = sharedContext->caps();
if (dimensions.width() > caps->maxTextureSize() ||
dimensions.height() > caps->maxTextureSize()) {
SKGPU_LOG_E("Texture creation failure: dimensions %d x %d too large.",
dimensions.width(), dimensions.height());
return {};
}
const DawnTextureSpec& dawnSpec = info.dawnTextureSpec();
if (dawnSpec.fUsage & wgpu::TextureUsage::TextureBinding && !caps->isTexturable(info)) {
return {};
}
if (dawnSpec.fUsage & wgpu::TextureUsage::RenderAttachment &&
!(caps->isRenderable(info) || DawnFormatIsDepthOrStencil(dawnSpec.fFormat))) {
return {};
}
if (dawnSpec.fUsage & wgpu::TextureUsage::StorageBinding && !caps->isStorage(info)) {
return {};
}
int numMipLevels = 1;
if (info.mipmapped() == Mipmapped::kYes) {
numMipLevels = SkMipmap::ComputeLevelCount(dimensions.width(), dimensions.height()) + 1;
}
wgpu::TextureDescriptor desc;
desc.label = texture_info_to_label(info, dawnSpec);
desc.usage = dawnSpec.fUsage;
desc.dimension = wgpu::TextureDimension::e2D;
desc.size.width = dimensions.width();
desc.size.height = dimensions.height();
desc.size.depthOrArrayLayers = 1;
desc.format = dawnSpec.fFormat;
desc.mipLevelCount = numMipLevels;
desc.sampleCount = info.numSamples();
desc.viewFormatCount = 0;
desc.viewFormats = nullptr;
auto texture = sharedContext->device().CreateTexture(&desc);
if (!texture) {
return {};
}
return texture;
}
DawnTexture::DawnTexture(const DawnSharedContext* sharedContext,
SkISize dimensions,
const TextureInfo& info,
wgpu::Texture texture,
wgpu::TextureView textureView,
Ownership ownership,
skgpu::Budgeted budgeted)
: Texture(sharedContext, dimensions, info, /*mutableState=*/nullptr, ownership, budgeted)
, fTexture(std::move(texture))
, fTextureView(std::move(textureView)) {}
sk_sp<Texture> DawnTexture::Make(const DawnSharedContext* sharedContext,
SkISize dimensions,
const TextureInfo& info,
skgpu::Budgeted budgeted) {
auto texture = MakeDawnTexture(sharedContext, dimensions, info);
if (!texture) {
return {};
}
auto textureView = texture.CreateView();
return sk_sp<Texture>(new DawnTexture(sharedContext,
dimensions,
info,
std::move(texture),
std::move(textureView),
Ownership::kOwned,
budgeted));
}
sk_sp<Texture> DawnTexture::MakeWrapped(const DawnSharedContext* sharedContext,
SkISize dimensions,
const TextureInfo& info,
wgpu::Texture texture) {
if (!texture) {
SKGPU_LOG_E("No valid texture passed into MakeWrapped\n");
return {};
}
auto textureView = texture.CreateView();
return sk_sp<Texture>(new DawnTexture(sharedContext,
dimensions,
info,
std::move(texture),
std::move(textureView),
Ownership::kWrapped,
skgpu::Budgeted::kNo));
}
sk_sp<Texture> DawnTexture::MakeWrapped(const DawnSharedContext* sharedContext,
SkISize dimensions,
const TextureInfo& info,
wgpu::TextureView textureView) {
if (!textureView) {
SKGPU_LOG_E("No valid texture passed into MakeWrapped\n");
return {};
}
return sk_sp<Texture>(new DawnTexture(sharedContext,
dimensions,
info,
nullptr,
std::move(textureView),
Ownership::kWrapped,
skgpu::Budgeted::kNo));
}
void DawnTexture::freeGpuData() {
fTexture = nullptr;
fTextureView = nullptr;
}
} // namespace skgpu::graphite