1 /*
2 * Copyright 2024 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7 #include "include/core/SkString.h"
8 #include "include/gpu/MutableTextureState.h"
9 #include "include/gpu/graphite/vk/VulkanGraphiteTypes.h"
10 #include "include/gpu/vk/VulkanMutableTextureState.h"
11 #include "src/gpu/graphite/BackendTexturePriv.h"
12 #include "src/gpu/graphite/vk/VulkanGraphiteTypesPriv.h"
13
14 #include <cstdint>
15
16 namespace skgpu::graphite {
17
18 class VulkanBackendTextureData final : public BackendTextureData {
19 public:
VulkanBackendTextureData(VulkanAlloc alloc,sk_sp<skgpu::MutableTextureState> mts,VkImage vImg)20 VulkanBackendTextureData(VulkanAlloc alloc, sk_sp<skgpu::MutableTextureState> mts, VkImage vImg)
21 : fMemoryAlloc(alloc), fMutableState(mts), fVkImage(vImg) {}
22
23 #if defined(SK_DEBUG)
type() const24 skgpu::BackendApi type() const override { return skgpu::BackendApi::kVulkan; }
25 #endif
26
image() const27 VkImage image() const { return fVkImage; }
memoryAllocator() const28 VulkanAlloc memoryAllocator() const { return fMemoryAlloc; }
mutableState() const29 sk_sp<skgpu::MutableTextureState> mutableState() const { return fMutableState; }
30
31 private:
32 VulkanAlloc fMemoryAlloc;
33 sk_sp<skgpu::MutableTextureState> fMutableState;
34 VkImage fVkImage;
35
copyTo(AnyBackendTextureData & dstData) const36 void copyTo(AnyBackendTextureData& dstData) const override {
37 // Don't assert that dstData has a Vulkan type() because it could be
38 // uninitialized and that assert would fail.
39 dstData.emplace<VulkanBackendTextureData>(fMemoryAlloc, fMutableState, fVkImage);
40 }
41
equal(const BackendTextureData * that) const42 bool equal(const BackendTextureData* that) const override {
43 SkASSERT(!that || that->type() == skgpu::BackendApi::kVulkan);
44 if (auto otherVk = static_cast<const VulkanBackendTextureData*>(that)) {
45 // We ignore the other two fields for the purpose of comparison.
46 return fVkImage == otherVk->fVkImage;
47 }
48 return false;
49 }
50 };
51
get_and_cast_data(const BackendTexture & tex)52 static const VulkanBackendTextureData* get_and_cast_data(const BackendTexture& tex) {
53 auto data = BackendTexturePriv::GetData(tex);
54 SkASSERT(!data || data->type() == skgpu::BackendApi::kVulkan);
55 return static_cast<const VulkanBackendTextureData*>(data);
56 }
57
get_and_cast_data(BackendTexture * tex)58 static VulkanBackendTextureData* get_and_cast_data(BackendTexture* tex) {
59 auto data = BackendTexturePriv::GetData(tex);
60 SkASSERT(!data || data->type() == skgpu::BackendApi::kVulkan);
61 return static_cast<VulkanBackendTextureData*>(data);
62 }
63
64 namespace BackendTextures {
MakeVulkan(SkISize dimensions,const VulkanTextureInfo & info,VkImageLayout layout,uint32_t queueFamilyIndex,VkImage image,VulkanAlloc vulkanMemoryAllocation)65 BackendTexture MakeVulkan(SkISize dimensions,
66 const VulkanTextureInfo& info,
67 VkImageLayout layout,
68 uint32_t queueFamilyIndex,
69 VkImage image,
70 VulkanAlloc vulkanMemoryAllocation) {
71 return BackendTexturePriv::Make(
72 dimensions,
73 TextureInfos::MakeVulkan(info),
74 VulkanBackendTextureData(
75 vulkanMemoryAllocation,
76 sk_make_sp<skgpu::MutableTextureState>(
77 skgpu::MutableTextureStates::MakeVulkan(layout, queueFamilyIndex)),
78 image));
79 }
80
GetVkImage(const BackendTexture & tex)81 VkImage GetVkImage(const BackendTexture& tex) {
82 if (!tex.isValid() || tex.backend() != skgpu::BackendApi::kVulkan) {
83 return VK_NULL_HANDLE;
84 }
85 const VulkanBackendTextureData* vkData = get_and_cast_data(tex);
86 SkASSERT(vkData);
87 return vkData->image();
88 }
89
GetVkImageLayout(const BackendTexture & tex)90 VkImageLayout GetVkImageLayout(const BackendTexture& tex) {
91 if (!tex.isValid() || tex.backend() != skgpu::BackendApi::kVulkan) {
92 return VK_IMAGE_LAYOUT_UNDEFINED;
93 }
94 const VulkanBackendTextureData* vkData = get_and_cast_data(tex);
95 SkASSERT(vkData);
96 return skgpu::MutableTextureStates::GetVkImageLayout(vkData->mutableState().get());
97 }
98
GetVkQueueFamilyIndex(const BackendTexture & tex)99 uint32_t GetVkQueueFamilyIndex(const BackendTexture& tex) {
100 if (!tex.isValid() || tex.backend() != skgpu::BackendApi::kVulkan) {
101 return 0;
102 }
103 const VulkanBackendTextureData* vkData = get_and_cast_data(tex);
104 SkASSERT(vkData);
105 return skgpu::MutableTextureStates::GetVkQueueFamilyIndex(vkData->mutableState().get());
106 }
107
GetMemoryAlloc(const BackendTexture & tex)108 VulkanAlloc GetMemoryAlloc(const BackendTexture& tex) {
109 if (!tex.isValid() || tex.backend() != skgpu::BackendApi::kVulkan) {
110 return {};
111 }
112 const VulkanBackendTextureData* vkData = get_and_cast_data(tex);
113 SkASSERT(vkData);
114 return vkData->memoryAllocator();
115 }
116
GetMutableState(const BackendTexture & tex)117 sk_sp<skgpu::MutableTextureState> GetMutableState(const BackendTexture& tex) {
118 if (!tex.isValid() || tex.backend() != skgpu::BackendApi::kVulkan) {
119 return {};
120 }
121 const VulkanBackendTextureData* vkData = get_and_cast_data(tex);
122 SkASSERT(vkData);
123 return vkData->mutableState();
124 }
125
SetMutableState(BackendTexture * tex,const skgpu::MutableTextureState & newState)126 void SetMutableState(BackendTexture* tex, const skgpu::MutableTextureState& newState) {
127 SkASSERT(tex);
128 if (!tex->isValid() || tex->backend() != skgpu::BackendApi::kVulkan) {
129 return;
130 }
131 VulkanBackendTextureData* vkData = get_and_cast_data(tex);
132 SkASSERT(vkData);
133 vkData->mutableState()->set(newState);
134 }
135
136 } // namespace BackendTextures
137
138 } // namespace skgpu::graphite
139