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_ASTC_4x4_UNORM_BLOCK: return kRGBA_SkColorChannelFlags;
67 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: return kRGBA_SkColorChannelFlags;
68 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: return kRGBA_SkColorChannelFlags;
69 case VK_FORMAT_R16_UNORM: return kRed_SkColorChannelFlag;
70 case VK_FORMAT_R16G16_UNORM: return kRG_SkColorChannelFlags;
71 case VK_FORMAT_R16G16B16A16_UNORM: return kRGBA_SkColorChannelFlags;
72 case VK_FORMAT_R16G16_SFLOAT: return kRG_SkColorChannelFlags;
73 case VK_FORMAT_S8_UINT: return 0;
74 case VK_FORMAT_D24_UNORM_S8_UINT: return 0;
75 case VK_FORMAT_D32_SFLOAT_S8_UINT: return 0;
76 default: return 0;
77 }
78 }
79
GrVkFormatDesc(VkFormat vkFormat)80 static constexpr GrColorFormatDesc GrVkFormatDesc(VkFormat vkFormat) {
81 switch (vkFormat) {
82 case VK_FORMAT_R8G8B8A8_UNORM:
83 return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
84 case VK_FORMAT_R8_UNORM:
85 return GrColorFormatDesc::MakeR(8, GrColorTypeEncoding::kUnorm);
86 case VK_FORMAT_B8G8R8A8_UNORM:
87 return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
88 case VK_FORMAT_R5G6B5_UNORM_PACK16:
89 return GrColorFormatDesc::MakeRGB(5, 6, 5, GrColorTypeEncoding::kUnorm);
90 case VK_FORMAT_R16G16B16A16_SFLOAT:
91 return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kFloat);
92 case VK_FORMAT_R16_SFLOAT:
93 return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kFloat);
94 case VK_FORMAT_R8G8B8_UNORM:
95 return GrColorFormatDesc::MakeRGB(8, GrColorTypeEncoding::kUnorm);
96 case VK_FORMAT_R8G8_UNORM:
97 return GrColorFormatDesc::MakeRG(8, GrColorTypeEncoding::kUnorm);
98 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
99 return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
100 case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
101 return GrColorFormatDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
102 case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
103 return GrColorFormatDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
104 case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
105 return GrColorFormatDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
106 case VK_FORMAT_R8G8B8A8_SRGB:
107 return GrColorFormatDesc::MakeRGBA(8, GrColorTypeEncoding::kSRGBUnorm);
108 case VK_FORMAT_R16_UNORM:
109 return GrColorFormatDesc::MakeR(16, GrColorTypeEncoding::kUnorm);
110 case VK_FORMAT_R16G16_UNORM:
111 return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kUnorm);
112 case VK_FORMAT_R16G16B16A16_UNORM:
113 return GrColorFormatDesc::MakeRGBA(16, GrColorTypeEncoding::kUnorm);
114 case VK_FORMAT_R16G16_SFLOAT:
115 return GrColorFormatDesc::MakeRG(16, GrColorTypeEncoding::kFloat);
116
117 // Compressed texture formats are not expected to have a description.
118 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: return GrColorFormatDesc::MakeInvalid();
119 case VK_FORMAT_BC1_RGB_UNORM_BLOCK: return GrColorFormatDesc::MakeInvalid();
120 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return GrColorFormatDesc::MakeInvalid();
121 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: return GrColorFormatDesc::MakeInvalid();
122 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: return GrColorFormatDesc::MakeInvalid();
123 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: return GrColorFormatDesc::MakeInvalid();
124
125 // This type only describes color channels.
126 case VK_FORMAT_S8_UINT: return GrColorFormatDesc::MakeInvalid();
127 case VK_FORMAT_D24_UNORM_S8_UINT: return GrColorFormatDesc::MakeInvalid();
128 case VK_FORMAT_D32_SFLOAT_S8_UINT: return GrColorFormatDesc::MakeInvalid();
129
130 default: return GrColorFormatDesc::MakeInvalid();
131 }
132 }
133
GrVkFormatBytesPerBlock(VkFormat vkFormat)134 static constexpr size_t GrVkFormatBytesPerBlock(VkFormat vkFormat) {
135 switch (vkFormat) {
136 case VK_FORMAT_R8G8B8A8_UNORM: return 4;
137 case VK_FORMAT_R8_UNORM: return 1;
138 case VK_FORMAT_B8G8R8A8_UNORM: return 4;
139 case VK_FORMAT_R5G6B5_UNORM_PACK16: return 2;
140 case VK_FORMAT_R16G16B16A16_SFLOAT: return 8;
141 case VK_FORMAT_R16_SFLOAT: return 2;
142 case VK_FORMAT_R8G8B8_UNORM: return 3;
143 case VK_FORMAT_R8G8_UNORM: return 2;
144 case VK_FORMAT_A2B10G10R10_UNORM_PACK32: return 4;
145 case VK_FORMAT_A2R10G10B10_UNORM_PACK32: return 4;
146 case VK_FORMAT_B4G4R4A4_UNORM_PACK16: return 2;
147 case VK_FORMAT_R4G4B4A4_UNORM_PACK16: return 2;
148 case VK_FORMAT_R8G8B8A8_SRGB: return 4;
149 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: return 8;
150 case VK_FORMAT_BC1_RGB_UNORM_BLOCK: return 8;
151 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return 8;
152 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: return 16; // astc block bytes
153 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: return 16; // astc block bytes
154 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: return 16; // astc block bytes
155 case VK_FORMAT_R16_UNORM: return 2;
156 case VK_FORMAT_R16G16_UNORM: return 4;
157 case VK_FORMAT_R16G16B16A16_UNORM: return 8;
158 case VK_FORMAT_R16G16_SFLOAT: return 4;
159 // Currently we are just over estimating this value to be used in gpu size calculations even
160 // though the actually size is probably less. We should instead treat planar formats similar
161 // to compressed textures that go through their own special query for calculating size.
162 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: return 3;
163 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: return 3;
164 case VK_FORMAT_S8_UINT: return 1;
165 case VK_FORMAT_D24_UNORM_S8_UINT: return 4;
166 case VK_FORMAT_D32_SFLOAT_S8_UINT: return 8;
167
168 default: return 0;
169 }
170 }
171
GrVkFormatStencilBits(VkFormat format)172 static constexpr int GrVkFormatStencilBits(VkFormat format) {
173 switch (format) {
174 case VK_FORMAT_S8_UINT:
175 return 8;
176 case VK_FORMAT_D24_UNORM_S8_UINT:
177 return 8;
178 case VK_FORMAT_D32_SFLOAT_S8_UINT:
179 return 8;
180 default:
181 return 0;
182 }
183 }
184
185 bool GrVkFormatNeedsYcbcrSampler(VkFormat format);
186
187 bool GrSampleCountToVkSampleCount(uint32_t samples, VkSampleCountFlagBits* vkSamples);
188
189 bool GrCompileVkShaderModule(GrVkGpu* gpu,
190 const SkSL::String& shaderString,
191 VkShaderStageFlagBits stage,
192 VkShaderModule* shaderModule,
193 VkPipelineShaderStageCreateInfo* stageInfo,
194 const SkSL::Program::Settings& settings,
195 SkSL::String* outSPIRV,
196 SkSL::Program::Inputs* outInputs);
197
198 bool GrInstallVkShaderModule(GrVkGpu* gpu,
199 const SkSL::String& spirv,
200 VkShaderStageFlagBits stage,
201 VkShaderModule* shaderModule,
202 VkPipelineShaderStageCreateInfo* stageInfo);
203
204 /**
205 * Returns true if the format is compressed.
206 */
207 bool GrVkFormatIsCompressed(VkFormat);
208
209 #if defined(SK_DEBUG) || GR_TEST_UTILS
GrVkFormatToStr(VkFormat vkFormat)210 static constexpr const char* GrVkFormatToStr(VkFormat vkFormat) {
211 switch (vkFormat) {
212 case VK_FORMAT_R8G8B8A8_UNORM: return "R8G8B8A8_UNORM";
213 case VK_FORMAT_R8_UNORM: return "R8_UNORM";
214 case VK_FORMAT_B8G8R8A8_UNORM: return "B8G8R8A8_UNORM";
215 case VK_FORMAT_R5G6B5_UNORM_PACK16: return "R5G6B5_UNORM_PACK16";
216 case VK_FORMAT_R16G16B16A16_SFLOAT: return "R16G16B16A16_SFLOAT";
217 case VK_FORMAT_R16_SFLOAT: return "R16_SFLOAT";
218 case VK_FORMAT_R8G8B8_UNORM: return "R8G8B8_UNORM";
219 case VK_FORMAT_R8G8_UNORM: return "R8G8_UNORM";
220 case VK_FORMAT_A2B10G10R10_UNORM_PACK32: return "A2B10G10R10_UNORM_PACK32";
221 case VK_FORMAT_A2R10G10B10_UNORM_PACK32: return "A2R10G10B10_UNORM_PACK32";
222 case VK_FORMAT_B4G4R4A4_UNORM_PACK16: return "B4G4R4A4_UNORM_PACK16";
223 case VK_FORMAT_R4G4B4A4_UNORM_PACK16: return "R4G4B4A4_UNORM_PACK16";
224 case VK_FORMAT_R32G32B32A32_SFLOAT: return "R32G32B32A32_SFLOAT";
225 case VK_FORMAT_R8G8B8A8_SRGB: return "R8G8B8A8_SRGB";
226 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: return "ETC2_R8G8B8_UNORM_BLOCK";
227 case VK_FORMAT_BC1_RGB_UNORM_BLOCK: return "BC1_RGB_UNORM_BLOCK";
228 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return "BC1_RGBA_UNORM_BLOCK";
229 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: return "ASTC_4x4_UNORM_BLOCK";
230 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: return "ASTC_6x6_UNORM_BLOCK";
231 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: return "ASTC_8x8_UNORM_BLOCK";
232 case VK_FORMAT_R16_UNORM: return "R16_UNORM";
233 case VK_FORMAT_R16G16_UNORM: return "R16G16_UNORM";
234 case VK_FORMAT_R16G16B16A16_UNORM: return "R16G16B16A16_UNORM";
235 case VK_FORMAT_R16G16_SFLOAT: return "R16G16_SFLOAT";
236 case VK_FORMAT_S8_UINT: return "S8_UINT";
237 case VK_FORMAT_D24_UNORM_S8_UINT: return "D24_UNORM_S8_UINT";
238 case VK_FORMAT_D32_SFLOAT_S8_UINT: return "D32_SFLOAT_S8_UINT";
239
240 default: return "Unknown";
241 }
242 }
243
244 #endif
245 #endif
246