1 /*
2 * Copyright 2015 Google Inc.
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 #ifndef GrVkUtil_DEFINED
9 #define GrVkUtil_DEFINED
10
11 #include "include/gpu/GrTypes.h"
12 #include "include/gpu/vk/GrVkTypes.h"
13 #include "include/private/SkMacros.h"
14 #include "src/gpu/GrColor.h"
15 #include "src/gpu/GrDataUtils.h"
16 #include "src/gpu/vk/GrVkInterface.h"
17 #include "src/sksl/ir/SkSLProgram.h"
18
19 class GrVkGpu;
20
21 // makes a Vk call on the interface
22 #define GR_VK_CALL(IFACE, X) (IFACE)->fFunctions.f##X
23
24 #define GR_VK_CALL_RESULT(GPU, RESULT, X) \
25 do { \
26 (RESULT) = GR_VK_CALL(GPU->vkInterface(), X); \
27 SkASSERT(VK_SUCCESS == RESULT || VK_ERROR_DEVICE_LOST == RESULT); \
28 if (RESULT != VK_SUCCESS && !GPU->isDeviceLost()) { \
29 SkDebugf("Failed vulkan call. Error: %d," #X "\n", RESULT); \
30 } \
31 GPU->checkVkResult(RESULT); \
32 } while (false)
33
34 #define GR_VK_CALL_RESULT_NOCHECK(GPU, RESULT, X) \
35 do { \
36 (RESULT) = GR_VK_CALL(GPU->vkInterface(), X); \
37 GPU->checkVkResult(RESULT); \
38 } while (false)
39
40 // same as GR_VK_CALL but checks for success
41 #define GR_VK_CALL_ERRCHECK(GPU, X) \
42 VkResult SK_MACRO_APPEND_LINE(ret); \
43 GR_VK_CALL_RESULT(GPU, SK_MACRO_APPEND_LINE(ret), X) \
44
45
46 bool GrVkFormatIsSupported(VkFormat);
47
GrVkFormatChannels(VkFormat vkFormat)48 static constexpr uint32_t GrVkFormatChannels(VkFormat vkFormat) {
49 switch (vkFormat) {
50 case VK_FORMAT_R8G8B8A8_UNORM: return kRGBA_SkColorChannelFlags;
51 case VK_FORMAT_R8_UNORM: return kRed_SkColorChannelFlag;
52 case VK_FORMAT_B8G8R8A8_UNORM: return kRGBA_SkColorChannelFlags;
53 case VK_FORMAT_R5G6B5_UNORM_PACK16: return kRGB_SkColorChannelFlags;
54 case VK_FORMAT_R16G16B16A16_SFLOAT: return kRGBA_SkColorChannelFlags;
55 case VK_FORMAT_R16_SFLOAT: return kRed_SkColorChannelFlag;
56 case VK_FORMAT_R8G8B8_UNORM: return kRGB_SkColorChannelFlags;
57 case VK_FORMAT_R8G8_UNORM: return kRG_SkColorChannelFlags;
58 case VK_FORMAT_A2B10G10R10_UNORM_PACK32: return kRGBA_SkColorChannelFlags;
59 case VK_FORMAT_A2R10G10B10_UNORM_PACK32: return kRGBA_SkColorChannelFlags;
60 case VK_FORMAT_B4G4R4A4_UNORM_PACK16: return kRGBA_SkColorChannelFlags;
61 case VK_FORMAT_R4G4B4A4_UNORM_PACK16: return kRGBA_SkColorChannelFlags;
62 case VK_FORMAT_R8G8B8A8_SRGB: return kRGBA_SkColorChannelFlags;
63 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: return kRGB_SkColorChannelFlags;
64 case VK_FORMAT_BC1_RGB_UNORM_BLOCK: return kRGB_SkColorChannelFlags;
65 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return kRGBA_SkColorChannelFlags;
66 case VK_FORMAT_R16_UNORM: return kRed_SkColorChannelFlag;
67 case VK_FORMAT_R16G16_UNORM: return kRG_SkColorChannelFlags;
68 case VK_FORMAT_R16G16B16A16_UNORM: return kRGBA_SkColorChannelFlags;
69 case VK_FORMAT_R16G16_SFLOAT: return kRG_SkColorChannelFlags;
70 case VK_FORMAT_S8_UINT: return 0;
71 case VK_FORMAT_D24_UNORM_S8_UINT: return 0;
72 case VK_FORMAT_D32_SFLOAT_S8_UINT: return 0;
73 default: return 0;
74 }
75 }
76
GrVkFormatDesc(VkFormat vkFormat)77 static constexpr GrColorFormatDesc GrVkFormatDesc(VkFormat vkFormat) {
78 switch (vkFormat) {
79 case VK_FORMAT_R8G8B8A8_UNORM:
80 return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
81 case VK_FORMAT_R8_UNORM:
82 return GrColorFormatDesc::MakeR(8, GrColorTypeEncoding::kUnorm);
83 case VK_FORMAT_B8G8R8A8_UNORM:
84 return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
85 case VK_FORMAT_R5G6B5_UNORM_PACK16:
86 return GrColorFormatDesc::MakeRGB(5, 6, 5, GrColorTypeEncoding::kUnorm);
87 case VK_FORMAT_R16G16B16A16_SFLOAT:
88 return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kFloat);
89 case VK_FORMAT_R16_SFLOAT:
90 return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kFloat);
91 case VK_FORMAT_R8G8B8_UNORM:
92 return GrColorFormatDesc::MakeRGB(8, GrColorTypeEncoding::kUnorm);
93 case VK_FORMAT_R8G8_UNORM:
94 return GrColorFormatDesc::MakeRG(8, GrColorTypeEncoding::kUnorm);
95 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
96 return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
97 case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
98 return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
99 case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
100 return GrColorFormatDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
101 case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
102 return GrColorFormatDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
103 case VK_FORMAT_R8G8B8A8_SRGB:
104 return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kSRGBUnorm);
105 case VK_FORMAT_R16_UNORM:
106 return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kUnorm);
107 case VK_FORMAT_R16G16_UNORM:
108 return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kUnorm);
109 case VK_FORMAT_R16G16B16A16_UNORM:
110 return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kUnorm);
111 case VK_FORMAT_R16G16_SFLOAT:
112 return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kFloat);
113
114 // Compressed texture formats are not expected to have a description.
115 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: return GrColorFormatDesc::MakeInvalid();
116 case VK_FORMAT_BC1_RGB_UNORM_BLOCK: return GrColorFormatDesc::MakeInvalid();
117 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return GrColorFormatDesc::MakeInvalid();
118
119 // This type only describes color channels.
120 case VK_FORMAT_S8_UINT: return GrColorFormatDesc::MakeInvalid();
121 case VK_FORMAT_D24_UNORM_S8_UINT: return GrColorFormatDesc::MakeInvalid();
122 case VK_FORMAT_D32_SFLOAT_S8_UINT: return GrColorFormatDesc::MakeInvalid();
123
124 default: return GrColorFormatDesc::MakeInvalid();
125 }
126 }
127
GrVkFormatBytesPerBlock(VkFormat vkFormat)128 static constexpr size_t GrVkFormatBytesPerBlock(VkFormat vkFormat) {
129 switch (vkFormat) {
130 case VK_FORMAT_R8G8B8A8_UNORM: return 4;
131 case VK_FORMAT_R8_UNORM: return 1;
132 case VK_FORMAT_B8G8R8A8_UNORM: return 4;
133 case VK_FORMAT_R5G6B5_UNORM_PACK16: return 2;
134 case VK_FORMAT_R16G16B16A16_SFLOAT: return 8;
135 case VK_FORMAT_R16_SFLOAT: return 2;
136 case VK_FORMAT_R8G8B8_UNORM: return 3;
137 case VK_FORMAT_R8G8_UNORM: return 2;
138 case VK_FORMAT_A2B10G10R10_UNORM_PACK32: return 4;
139 case VK_FORMAT_A2R10G10B10_UNORM_PACK32: return 4;
140 case VK_FORMAT_B4G4R4A4_UNORM_PACK16: return 2;
141 case VK_FORMAT_R4G4B4A4_UNORM_PACK16: return 2;
142 case VK_FORMAT_R8G8B8A8_SRGB: return 4;
143 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: return 8;
144 case VK_FORMAT_BC1_RGB_UNORM_BLOCK: return 8;
145 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return 8;
146 case VK_FORMAT_R16_UNORM: return 2;
147 case VK_FORMAT_R16G16_UNORM: return 4;
148 case VK_FORMAT_R16G16B16A16_UNORM: return 8;
149 case VK_FORMAT_R16G16_SFLOAT: return 4;
150 // Currently we are just over estimating this value to be used in gpu size calculations even
151 // though the actually size is probably less. We should instead treat planar formats similar
152 // to compressed textures that go through their own special query for calculating size.
153 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: return 3;
154 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: return 3;
155 case VK_FORMAT_S8_UINT: return 1;
156 case VK_FORMAT_D24_UNORM_S8_UINT: return 4;
157 case VK_FORMAT_D32_SFLOAT_S8_UINT: return 8;
158
159 default: return 0;
160 }
161 }
162
GrVkFormatStencilBits(VkFormat format)163 static constexpr int GrVkFormatStencilBits(VkFormat format) {
164 switch (format) {
165 case VK_FORMAT_S8_UINT:
166 return 8;
167 case VK_FORMAT_D24_UNORM_S8_UINT:
168 return 8;
169 case VK_FORMAT_D32_SFLOAT_S8_UINT:
170 return 8;
171 default:
172 return 0;
173 }
174 }
175
176 bool GrVkFormatNeedsYcbcrSampler(VkFormat format);
177
178 bool GrSampleCountToVkSampleCount(uint32_t samples, VkSampleCountFlagBits* vkSamples);
179
180 bool GrCompileVkShaderModule(GrVkGpu* gpu,
181 const SkSL::String& shaderString,
182 VkShaderStageFlagBits stage,
183 VkShaderModule* shaderModule,
184 VkPipelineShaderStageCreateInfo* stageInfo,
185 const SkSL::Program::Settings& settings,
186 SkSL::String* outSPIRV,
187 SkSL::Program::Inputs* outInputs);
188
189 bool GrInstallVkShaderModule(GrVkGpu* gpu,
190 const SkSL::String& spirv,
191 VkShaderStageFlagBits stage,
192 VkShaderModule* shaderModule,
193 VkPipelineShaderStageCreateInfo* stageInfo);
194
195 /**
196 * Returns true if the format is compressed.
197 */
198 bool GrVkFormatIsCompressed(VkFormat);
199
200 #if defined(SK_DEBUG) || GR_TEST_UTILS
GrVkFormatToStr(VkFormat vkFormat)201 static constexpr const char* GrVkFormatToStr(VkFormat vkFormat) {
202 switch (vkFormat) {
203 case VK_FORMAT_R8G8B8A8_UNORM: return "R8G8B8A8_UNORM";
204 case VK_FORMAT_R8_UNORM: return "R8_UNORM";
205 case VK_FORMAT_B8G8R8A8_UNORM: return "B8G8R8A8_UNORM";
206 case VK_FORMAT_R5G6B5_UNORM_PACK16: return "R5G6B5_UNORM_PACK16";
207 case VK_FORMAT_R16G16B16A16_SFLOAT: return "R16G16B16A16_SFLOAT";
208 case VK_FORMAT_R16_SFLOAT: return "R16_SFLOAT";
209 case VK_FORMAT_R8G8B8_UNORM: return "R8G8B8_UNORM";
210 case VK_FORMAT_R8G8_UNORM: return "R8G8_UNORM";
211 case VK_FORMAT_A2B10G10R10_UNORM_PACK32: return "A2B10G10R10_UNORM_PACK32";
212 case VK_FORMAT_A2R10G10B10_UNORM_PACK32: return "A2R10G10B10_UNORM_PACK32";
213 case VK_FORMAT_B4G4R4A4_UNORM_PACK16: return "B4G4R4A4_UNORM_PACK16";
214 case VK_FORMAT_R4G4B4A4_UNORM_PACK16: return "R4G4B4A4_UNORM_PACK16";
215 case VK_FORMAT_R32G32B32A32_SFLOAT: return "R32G32B32A32_SFLOAT";
216 case VK_FORMAT_R8G8B8A8_SRGB: return "R8G8B8A8_SRGB";
217 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: return "ETC2_R8G8B8_UNORM_BLOCK";
218 case VK_FORMAT_BC1_RGB_UNORM_BLOCK: return "BC1_RGB_UNORM_BLOCK";
219 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return "BC1_RGBA_UNORM_BLOCK";
220 case VK_FORMAT_R16_UNORM: return "R16_UNORM";
221 case VK_FORMAT_R16G16_UNORM: return "R16G16_UNORM";
222 case VK_FORMAT_R16G16B16A16_UNORM: return "R16G16B16A16_UNORM";
223 case VK_FORMAT_R16G16_SFLOAT: return "R16G16_SFLOAT";
224 case VK_FORMAT_S8_UINT: return "S8_UINT";
225 case VK_FORMAT_D24_UNORM_S8_UINT: return "D24_UNORM_S8_UINT";
226 case VK_FORMAT_D32_SFLOAT_S8_UINT: return "D32_SFLOAT_S8_UINT";
227
228 default: return "Unknown";
229 }
230 }
231
232 #endif
233 #endif
234