/src/skia/src/gpu/graphite/vk/VulkanSampler.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2023 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 | | |
8 | | #include "src/gpu/graphite/vk/VulkanSampler.h" |
9 | | |
10 | | #include "include/core/SkSamplingOptions.h" |
11 | | #include "src/gpu/graphite/vk/VulkanCaps.h" |
12 | | #include "src/gpu/graphite/vk/VulkanGraphiteUtilsPriv.h" |
13 | | |
14 | | namespace skgpu::graphite { |
15 | | |
16 | | VulkanSampler::VulkanSampler(const VulkanSharedContext* sharedContext, |
17 | | const SamplerDesc& desc, |
18 | | VkSampler sampler, |
19 | | sk_sp<VulkanYcbcrConversion> ycbcrConversion) |
20 | | : Sampler(sharedContext) |
21 | | , fDesc(desc) |
22 | | , fSampler(sampler) |
23 | 0 | , fYcbcrConversion(ycbcrConversion) {} |
24 | | |
25 | 0 | static VkSamplerAddressMode tile_mode_to_vk_sampler_address(SkTileMode tileMode) { |
26 | 0 | switch (tileMode) { |
27 | 0 | case SkTileMode::kClamp: |
28 | 0 | return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; |
29 | 0 | case SkTileMode::kRepeat: |
30 | 0 | return VK_SAMPLER_ADDRESS_MODE_REPEAT; |
31 | 0 | case SkTileMode::kMirror: |
32 | 0 | return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; |
33 | 0 | case SkTileMode::kDecal: |
34 | 0 | return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; |
35 | 0 | } |
36 | 0 | SkUNREACHABLE; |
37 | 0 | } |
38 | | |
39 | | sk_sp<VulkanSampler> VulkanSampler::Make( |
40 | | const VulkanSharedContext* sharedContext, |
41 | | const SamplerDesc& desc, |
42 | 0 | sk_sp<VulkanYcbcrConversion> ycbcrConversion) { |
43 | 0 | VkSamplerCreateInfo samplerInfo; |
44 | 0 | memset(&samplerInfo, 0, sizeof(VkSamplerCreateInfo)); |
45 | 0 | samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; |
46 | |
|
47 | 0 | void* pNext = nullptr; |
48 | 0 | VkSamplerYcbcrConversionInfo conversionInfo; |
49 | 0 | if (ycbcrConversion) { |
50 | 0 | conversionInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO; |
51 | 0 | conversionInfo.pNext = nullptr; |
52 | 0 | conversionInfo.conversion = ycbcrConversion->ycbcrConversion(); |
53 | 0 | pNext = &conversionInfo; |
54 | 0 | } |
55 | |
|
56 | 0 | samplerInfo.pNext = pNext; |
57 | 0 | samplerInfo.flags = 0; |
58 | |
|
59 | 0 | VkFilter minMagFilter = [&] { |
60 | 0 | switch (desc.samplingOptions().filter) { |
61 | 0 | case SkFilterMode::kNearest: return VK_FILTER_NEAREST; |
62 | 0 | case SkFilterMode::kLinear: return VK_FILTER_LINEAR; |
63 | 0 | } |
64 | 0 | SkUNREACHABLE; |
65 | 0 | }(); |
66 | |
|
67 | 0 | VkSamplerMipmapMode mipmapMode = [&] { |
68 | 0 | switch (desc.samplingOptions().mipmap) { |
69 | | // There is no disable mode. We use max level to disable mip mapping. |
70 | | // It may make more sense to use NEAREST for kNone but Chrome pixel tests have |
71 | | // been dependent on subtle rendering differences introduced by switching this. |
72 | 0 | case SkMipmapMode::kNone: return VK_SAMPLER_MIPMAP_MODE_LINEAR; |
73 | 0 | case SkMipmapMode::kNearest: return VK_SAMPLER_MIPMAP_MODE_NEAREST; |
74 | 0 | case SkMipmapMode::kLinear: return VK_SAMPLER_MIPMAP_MODE_LINEAR; |
75 | 0 | } |
76 | 0 | SkUNREACHABLE; |
77 | 0 | }(); |
78 | |
|
79 | 0 | samplerInfo.magFilter = minMagFilter; |
80 | 0 | samplerInfo.minFilter = minMagFilter; |
81 | 0 | samplerInfo.mipmapMode = mipmapMode; |
82 | 0 | samplerInfo.addressModeU = tile_mode_to_vk_sampler_address(desc.tileModeX()); |
83 | 0 | samplerInfo.addressModeV = tile_mode_to_vk_sampler_address(desc.tileModeY()); |
84 | 0 | samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; |
85 | 0 | samplerInfo.mipLodBias = 0; |
86 | 0 | samplerInfo.anisotropyEnable = VK_FALSE; |
87 | 0 | samplerInfo.maxAnisotropy = 1; // TODO: when we start using aniso, need to add to key |
88 | 0 | samplerInfo.compareEnable = VK_FALSE; |
89 | 0 | samplerInfo.compareOp = VK_COMPARE_OP_NEVER; |
90 | | // Vulkan doesn't have a direct mapping to use nearest or linear filters for minFilter since |
91 | | // there is always a mipmapMode. To get the same effect we can set minLod = maxLod = 0.0. |
92 | | // This works since our min and mag filters are the same (this forces us to use mag on the 0 |
93 | | // level mip). If the filters weren't the same we could set min = 0 and max = 0.25 to force |
94 | | // the minFilter on mip level 0. |
95 | 0 | samplerInfo.minLod = 0; |
96 | 0 | samplerInfo.maxLod = (desc.samplingOptions().mipmap == SkMipmapMode::kNone) ? 0.0f |
97 | 0 | : VK_LOD_CLAMP_NONE; |
98 | 0 | samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; |
99 | 0 | samplerInfo.unnormalizedCoordinates = VK_FALSE; |
100 | |
|
101 | 0 | VkSampler sampler; |
102 | 0 | VkResult result; |
103 | 0 | VULKAN_CALL_RESULT(sharedContext, |
104 | 0 | result, |
105 | 0 | CreateSampler(sharedContext->device(), &samplerInfo, nullptr, &sampler)); |
106 | 0 | if (result != VK_SUCCESS) { |
107 | 0 | return nullptr; |
108 | 0 | } |
109 | | |
110 | 0 | return sk_sp<VulkanSampler>(new VulkanSampler(sharedContext, |
111 | 0 | desc, |
112 | 0 | sampler, |
113 | 0 | std::move(ycbcrConversion))); |
114 | 0 | } Unexecuted instantiation: skgpu::graphite::VulkanSampler::Make(skgpu::graphite::VulkanSharedContext const*, skgpu::graphite::SamplerDesc const&, sk_sp<skgpu::graphite::VulkanYcbcrConversion>) Unexecuted instantiation: skgpu::graphite::VulkanSampler::Make(skgpu::graphite::VulkanSharedContext const*, skgpu::graphite::SamplerDesc const&, sk_sp<skgpu::graphite::VulkanYcbcrConversion>) |
115 | | |
116 | 0 | void VulkanSampler::freeGpuData() { |
117 | 0 | const VulkanSharedContext* sharedContext = |
118 | 0 | static_cast<const VulkanSharedContext*>(this->sharedContext()); |
119 | 0 | SkASSERT(fSampler); |
120 | 0 | VULKAN_CALL(sharedContext->interface(), |
121 | 0 | DestroySampler(sharedContext->device(), fSampler, nullptr)); |
122 | 0 | fSampler = VK_NULL_HANDLE; |
123 | 0 | } Unexecuted instantiation: skgpu::graphite::VulkanSampler::freeGpuData() Unexecuted instantiation: skgpu::graphite::VulkanSampler::freeGpuData() |
124 | | |
125 | | } // namespace skgpu::graphite |
126 | | |