1 // Copyright 2019 The Amber Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/vulkan/sampler.h"
16 
17 namespace amber {
18 namespace vulkan {
19 namespace {
20 
GetVkAddressMode(AddressMode mode)21 VkSamplerAddressMode GetVkAddressMode(AddressMode mode) {
22   switch (mode) {
23     case AddressMode::kRepeat:
24       return VK_SAMPLER_ADDRESS_MODE_REPEAT;
25     case AddressMode::kMirroredRepeat:
26       return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
27     case AddressMode::kClampToEdge:
28       return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
29     case AddressMode::kClampToBorder:
30       return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
31     default:
32       assert(mode == AddressMode::kMirrorClampToEdge);
33       return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
34   }
35 }
36 
GetVkBorderColor(BorderColor color)37 VkBorderColor GetVkBorderColor(BorderColor color) {
38   switch (color) {
39     case BorderColor::kFloatTransparentBlack:
40       return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
41     case BorderColor::kIntTransparentBlack:
42       return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
43     case BorderColor::kFloatOpaqueBlack:
44       return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
45     case BorderColor::kIntOpaqueBlack:
46       return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
47     case BorderColor::kFloatOpaqueWhite:
48       return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
49     default:
50       assert(color == BorderColor::kIntOpaqueWhite);
51       return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
52   }
53 }
54 
ToVkCompareOp(CompareOp op)55 VkCompareOp ToVkCompareOp(CompareOp op) {
56   switch (op) {
57     case CompareOp::kNever:
58       return VK_COMPARE_OP_NEVER;
59     case CompareOp::kLess:
60       return VK_COMPARE_OP_LESS;
61     case CompareOp::kEqual:
62       return VK_COMPARE_OP_EQUAL;
63     case CompareOp::kLessOrEqual:
64       return VK_COMPARE_OP_LESS_OR_EQUAL;
65     case CompareOp::kGreater:
66       return VK_COMPARE_OP_GREATER;
67     case CompareOp::kNotEqual:
68       return VK_COMPARE_OP_NOT_EQUAL;
69     case CompareOp::kGreaterOrEqual:
70       return VK_COMPARE_OP_GREATER_OR_EQUAL;
71     case CompareOp::kAlways:
72       return VK_COMPARE_OP_ALWAYS;
73     case CompareOp::kUnknown:
74       break;
75   }
76   assert(false && "Vulkan::Unknown CompareOp");
77   return VK_COMPARE_OP_NEVER;
78 }
79 
80 }  // namespace
81 
Sampler(Device * device)82 Sampler::Sampler(Device* device) : device_(device) {}
83 
CreateSampler(amber::Sampler * sampler)84 Result Sampler::CreateSampler(amber::Sampler* sampler) {
85   VkSamplerCreateInfo sampler_info = VkSamplerCreateInfo();
86   sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
87   sampler_info.magFilter = sampler->GetMagFilter() == FilterType::kLinear
88                                ? VK_FILTER_LINEAR
89                                : VK_FILTER_NEAREST;
90   sampler_info.minFilter = sampler->GetMinFilter() == FilterType::kLinear
91                                ? VK_FILTER_LINEAR
92                                : VK_FILTER_NEAREST;
93   sampler_info.mipmapMode = sampler->GetMipmapMode() == FilterType::kLinear
94                                 ? VK_SAMPLER_MIPMAP_MODE_LINEAR
95                                 : VK_SAMPLER_MIPMAP_MODE_NEAREST;
96   sampler_info.addressModeU = GetVkAddressMode(sampler->GetAddressModeU());
97   sampler_info.addressModeV = GetVkAddressMode(sampler->GetAddressModeV());
98   sampler_info.addressModeW = GetVkAddressMode(sampler->GetAddressModeW());
99   sampler_info.borderColor = GetVkBorderColor(sampler->GetBorderColor());
100   sampler_info.minLod = sampler->GetMinLOD();
101   sampler_info.maxLod = sampler->GetMaxLOD();
102   sampler_info.unnormalizedCoordinates =
103       (sampler->GetNormalizedCoords() ? VK_FALSE : VK_TRUE);
104   sampler_info.compareEnable =
105       (sampler->GetCompareEnable() ? VK_TRUE : VK_FALSE);
106   sampler_info.compareOp = ToVkCompareOp(sampler->GetCompareOp());
107 
108   if (device_->GetPtrs()->vkCreateSampler(device_->GetVkDevice(), &sampler_info,
109                                           nullptr, &sampler_) != VK_SUCCESS) {
110     return Result("Vulkan::Calling vkCreateSampler Fail");
111   }
112 
113   return {};
114 }
115 
~Sampler()116 Sampler::~Sampler() {
117   if (sampler_ != VK_NULL_HANDLE) {
118     device_->GetPtrs()->vkDestroySampler(device_->GetVkDevice(), sampler_,
119                                          nullptr);
120   }
121 }
122 
123 }  // namespace vulkan
124 }  // namespace amber
125