blob: 4806ca2b300668bee4ba51a4f5ddf9cceef9fb96 [file] [log] [blame]
/*
* Copyright 2024 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/core/SkString.h"
#include "include/gpu/graphite/dawn/DawnGraphiteTypes.h"
#include "src/gpu/graphite/BackendTexturePriv.h"
#include "src/gpu/graphite/dawn/DawnGraphiteUtils.h"
#include "webgpu/webgpu_cpp.h" // NO_G3_REWRITE
#include <cstdint>
namespace skgpu::graphite {
class DawnBackendTextureData final : public BackendTextureData {
public:
DawnBackendTextureData(WGPUTexture tex, WGPUTextureView tv) : fTexture(tex), fTextureView(tv) {}
#if defined(SK_DEBUG)
skgpu::BackendApi type() const override { return skgpu::BackendApi::kDawn; }
#endif
WGPUTexture texture() const { return fTexture; }
WGPUTextureView textureView() const { return fTextureView; }
private:
WGPUTexture fTexture;
WGPUTextureView fTextureView;
void copyTo(AnyBackendTextureData& dstData) const override {
// Don't assert that dstData has a Dawn type() because it could be
// uninitialized and that assert would fail.
dstData.emplace<DawnBackendTextureData>(fTexture, fTextureView);
}
bool equal(const BackendTextureData* that) const override {
SkASSERT(!that || that->type() == skgpu::BackendApi::kDawn);
if (auto otherDawn = static_cast<const DawnBackendTextureData*>(that)) {
return fTexture == otherDawn->fTexture && fTextureView == otherDawn->fTextureView;
}
return false;
}
};
static const DawnBackendTextureData* get_and_cast_data(const BackendTexture& tex) {
auto data = BackendTexturePriv::GetData(tex);
SkASSERT(!data || data->type() == skgpu::BackendApi::kDawn);
return static_cast<const DawnBackendTextureData*>(data);
}
// When we only have a WGPUTextureView we can't actually take advantage of these TextureUsage bits
// because they require having the WGPUTexture.
static DawnTextureInfo strip_copy_usage(const DawnTextureInfo& info) {
DawnTextureInfo result = info;
result.fUsage &= ~(wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc);
return result;
}
namespace BackendTextures {
BackendTexture MakeDawn(WGPUTexture texture) {
return BackendTexturePriv::Make(
{
static_cast<int32_t>(wgpuTextureGetWidth(texture)),
static_cast<int32_t>(wgpuTextureGetHeight(texture)),
},
TextureInfos::MakeDawn(texture),
DawnBackendTextureData(texture, nullptr));
}
BackendTexture MakeDawn(SkISize planeDimensions, const DawnTextureInfo& info, WGPUTexture texture) {
#if defined(__EMSCRIPTEN__)
SkASSERT(info.fAspect == wgpu::TextureAspect::All);
#else
SkASSERT(info.fAspect == wgpu::TextureAspect::All ||
info.fAspect == wgpu::TextureAspect::Plane0Only ||
info.fAspect == wgpu::TextureAspect::Plane1Only ||
info.fAspect == wgpu::TextureAspect::Plane2Only);
#endif
return BackendTexturePriv::Make(planeDimensions,
TextureInfos::MakeDawn(info),
DawnBackendTextureData(texture, nullptr));
}
BackendTexture MakeDawn(SkISize dimensions,
const DawnTextureInfo& info,
WGPUTextureView textureView) {
return BackendTexturePriv::Make(dimensions,
TextureInfos::MakeDawn(strip_copy_usage(info)),
DawnBackendTextureData(nullptr, textureView));
}
WGPUTexture GetDawnTexturePtr(const BackendTexture& tex) {
if (!tex.isValid() || tex.backend() != skgpu::BackendApi::kDawn) {
return nullptr;
}
const DawnBackendTextureData* dawnData = get_and_cast_data(tex);
SkASSERT(dawnData);
return dawnData->texture();
}
WGPUTextureView GetDawnTextureViewPtr(const BackendTexture& tex) {
if (!tex.isValid() || tex.backend() != skgpu::BackendApi::kDawn) {
return nullptr;
}
const DawnBackendTextureData* dawnData = get_and_cast_data(tex);
SkASSERT(dawnData);
return dawnData->textureView();
}
} // namespace BackendTextures
} // namespace skgpu::graphite