Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/lavapipe/lvp_formats.c
4565 views
1
/*
2
* Copyright © 2019 Red Hat.
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#include "lvp_private.h"
25
#include "util/format/u_format.h"
26
#include "util/u_math.h"
27
#include "vk_util.h"
28
29
static bool lvp_is_filter_minmax_format_supported(VkFormat format)
30
{
31
/* From the Vulkan spec 1.1.71:
32
*
33
* "The following formats must support the
34
* VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT feature with
35
* VK_IMAGE_TILING_OPTIMAL, if they support
36
* VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT."
37
*/
38
/* TODO: enable more formats. */
39
switch (format) {
40
case VK_FORMAT_R8_UNORM:
41
case VK_FORMAT_R8_SNORM:
42
case VK_FORMAT_R16_UNORM:
43
case VK_FORMAT_R16_SNORM:
44
case VK_FORMAT_R16_SFLOAT:
45
case VK_FORMAT_R32_SFLOAT:
46
case VK_FORMAT_D16_UNORM:
47
case VK_FORMAT_X8_D24_UNORM_PACK32:
48
case VK_FORMAT_D32_SFLOAT:
49
case VK_FORMAT_D16_UNORM_S8_UINT:
50
case VK_FORMAT_D24_UNORM_S8_UINT:
51
case VK_FORMAT_D32_SFLOAT_S8_UINT:
52
return true;
53
default:
54
return false;
55
}
56
}
57
58
static void
59
lvp_physical_device_get_format_properties(struct lvp_physical_device *physical_device,
60
VkFormat format,
61
VkFormatProperties *out_properties)
62
{
63
enum pipe_format pformat = lvp_vk_format_to_pipe_format(format);
64
unsigned features = 0, buffer_features = 0;
65
if (pformat == PIPE_FORMAT_NONE) {
66
out_properties->linearTilingFeatures = 0;
67
out_properties->optimalTilingFeatures = 0;
68
out_properties->bufferFeatures = 0;
69
return;
70
}
71
72
if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
73
PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_DEPTH_STENCIL)) {
74
out_properties->linearTilingFeatures = 0;
75
out_properties->optimalTilingFeatures = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
76
VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
77
VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
78
79
if (lvp_is_filter_minmax_format_supported(format))
80
out_properties->optimalTilingFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
81
out_properties->bufferFeatures = 0;
82
return;
83
}
84
85
if (util_format_is_compressed(pformat)) {
86
if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
87
PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
88
features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
89
features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT;
90
features |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
91
features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
92
}
93
out_properties->linearTilingFeatures = features;
94
out_properties->optimalTilingFeatures = features;
95
out_properties->bufferFeatures = buffer_features;
96
return;
97
}
98
99
if (!util_format_is_srgb(pformat) &&
100
physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
101
PIPE_BUFFER, 0, 0, PIPE_BIND_VERTEX_BUFFER)) {
102
buffer_features |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
103
}
104
105
if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
106
PIPE_BUFFER, 0, 0, PIPE_BIND_CONSTANT_BUFFER)) {
107
buffer_features |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
108
}
109
110
if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
111
PIPE_BUFFER, 0, 0, PIPE_BIND_SHADER_IMAGE)) {
112
buffer_features |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
113
}
114
115
if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
116
PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW)) {
117
features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
118
if (!util_format_is_pure_integer(pformat))
119
features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
120
if (lvp_is_filter_minmax_format_supported(format))
121
features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
122
}
123
124
if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
125
PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_RENDER_TARGET)) {
126
features |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
127
/* SNORM blending on llvmpipe fails CTS - disable for now */
128
if (!util_format_is_snorm(pformat))
129
features |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
130
}
131
132
if (physical_device->pscreen->is_format_supported(physical_device->pscreen, pformat,
133
PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SHADER_IMAGE)) {
134
features |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
135
}
136
137
if (pformat == PIPE_FORMAT_R32_UINT || pformat == PIPE_FORMAT_R32_SINT) {
138
features |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
139
buffer_features |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
140
}
141
142
if (pformat == PIPE_FORMAT_R11G11B10_FLOAT || pformat == PIPE_FORMAT_R9G9B9E5_FLOAT)
143
features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT;
144
145
if (features && buffer_features != VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)
146
features |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
147
if (pformat == PIPE_FORMAT_B5G6R5_UNORM)
148
features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
149
if ((pformat != PIPE_FORMAT_R9G9B9E5_FLOAT) && util_format_get_nr_components(pformat) != 3 &&
150
pformat != PIPE_FORMAT_R10G10B10A2_SNORM && pformat != PIPE_FORMAT_B10G10R10A2_SNORM &&
151
pformat != PIPE_FORMAT_B10G10R10A2_UNORM) {
152
features |= VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
153
}
154
out_properties->linearTilingFeatures = features;
155
out_properties->optimalTilingFeatures = features;
156
out_properties->bufferFeatures = buffer_features;
157
return;
158
}
159
160
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceFormatProperties2(
161
VkPhysicalDevice physicalDevice,
162
VkFormat format,
163
VkFormatProperties2* pFormatProperties)
164
{
165
LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
166
167
lvp_physical_device_get_format_properties(physical_device,
168
format,
169
&pFormatProperties->formatProperties);
170
}
171
static VkResult lvp_get_image_format_properties(struct lvp_physical_device *physical_device,
172
const VkPhysicalDeviceImageFormatInfo2 *info,
173
VkImageFormatProperties *pImageFormatProperties)
174
{
175
VkFormatProperties format_props;
176
VkFormatFeatureFlags format_feature_flags;
177
VkExtent3D maxExtent;
178
uint32_t maxMipLevels;
179
uint32_t maxArraySize;
180
VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
181
enum pipe_format pformat = lvp_vk_format_to_pipe_format(info->format);
182
lvp_physical_device_get_format_properties(physical_device, info->format,
183
&format_props);
184
if (info->tiling == VK_IMAGE_TILING_LINEAR) {
185
format_feature_flags = format_props.linearTilingFeatures;
186
} else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
187
format_feature_flags = format_props.optimalTilingFeatures;
188
} else {
189
unreachable("bad VkImageTiling");
190
}
191
192
if (format_feature_flags == 0)
193
goto unsupported;
194
195
uint32_t max_2d_ext = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_2D_SIZE);
196
uint32_t max_layers = physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS);
197
switch (info->type) {
198
default:
199
unreachable("bad vkimage type\n");
200
case VK_IMAGE_TYPE_1D:
201
if (util_format_is_compressed(pformat))
202
goto unsupported;
203
204
maxExtent.width = max_2d_ext;
205
maxExtent.height = 1;
206
maxExtent.depth = 1;
207
maxMipLevels = util_logbase2(max_2d_ext) + 1;
208
maxArraySize = max_layers;
209
break;
210
case VK_IMAGE_TYPE_2D:
211
maxExtent.width = max_2d_ext;
212
maxExtent.height = max_2d_ext;
213
maxExtent.depth = 1;
214
maxMipLevels = util_logbase2(max_2d_ext) + 1;
215
maxArraySize = max_layers;
216
if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
217
!(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
218
!util_format_is_compressed(pformat) &&
219
(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)))
220
sampleCounts |= VK_SAMPLE_COUNT_4_BIT;
221
break;
222
case VK_IMAGE_TYPE_3D:
223
maxExtent.width = max_2d_ext;
224
maxExtent.height = max_2d_ext;
225
maxExtent.depth = (1 << physical_device->pscreen->get_param(physical_device->pscreen, PIPE_CAP_MAX_TEXTURE_3D_LEVELS));
226
maxMipLevels = util_logbase2(max_2d_ext) + 1;
227
maxArraySize = 1;
228
break;
229
}
230
231
if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
232
if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
233
goto unsupported;
234
}
235
}
236
237
if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
238
if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
239
goto unsupported;
240
}
241
}
242
243
if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
244
if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
245
goto unsupported;
246
}
247
}
248
249
if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
250
if (!(format_feature_flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
251
goto unsupported;
252
}
253
}
254
255
if (info->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
256
if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {
257
goto unsupported;
258
}
259
}
260
261
if (info->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
262
if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) {
263
goto unsupported;
264
}
265
}
266
267
if (info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
268
if (!(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
269
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))) {
270
goto unsupported;
271
}
272
}
273
274
*pImageFormatProperties = (VkImageFormatProperties) {
275
.maxExtent = maxExtent,
276
.maxMipLevels = maxMipLevels,
277
.maxArrayLayers = maxArraySize,
278
.sampleCounts = sampleCounts,
279
280
/* FINISHME: Accurately calculate
281
* VkImageFormatProperties::maxResourceSize.
282
*/
283
.maxResourceSize = UINT32_MAX,
284
};
285
return VK_SUCCESS;
286
unsupported:
287
*pImageFormatProperties = (VkImageFormatProperties) {
288
.maxExtent = { 0, 0, 0 },
289
.maxMipLevels = 0,
290
.maxArrayLayers = 0,
291
.sampleCounts = 0,
292
.maxResourceSize = 0,
293
};
294
295
return VK_ERROR_FORMAT_NOT_SUPPORTED;
296
}
297
298
VKAPI_ATTR VkResult VKAPI_CALL lvp_GetPhysicalDeviceImageFormatProperties2(
299
VkPhysicalDevice physicalDevice,
300
const VkPhysicalDeviceImageFormatInfo2 *base_info,
301
VkImageFormatProperties2 *base_props)
302
{
303
LVP_FROM_HANDLE(lvp_physical_device, physical_device, physicalDevice);
304
const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
305
VkExternalImageFormatProperties *external_props = NULL;
306
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
307
VkResult result;
308
result = lvp_get_image_format_properties(physical_device, base_info,
309
&base_props->imageFormatProperties);
310
if (result != VK_SUCCESS)
311
return result;
312
313
vk_foreach_struct_const(s, base_info->pNext) {
314
switch (s->sType) {
315
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
316
external_info = (const void *) s;
317
break;
318
default:
319
break;
320
}
321
}
322
323
/* Extract output structs */
324
vk_foreach_struct(s, base_props->pNext) {
325
switch (s->sType) {
326
case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
327
external_props = (void *) s;
328
break;
329
case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
330
ycbcr_props = (void *) s;
331
break;
332
default:
333
break;
334
}
335
}
336
337
if (external_info && external_info->handleType != 0) {
338
external_props->externalMemoryProperties = (VkExternalMemoryProperties) {
339
.externalMemoryFeatures = 0,
340
.exportFromImportedHandleTypes = 0,
341
.compatibleHandleTypes = 0,
342
};
343
}
344
if (ycbcr_props)
345
ycbcr_props->combinedImageSamplerDescriptorCount = 0;
346
return VK_SUCCESS;
347
}
348
349
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceSparseImageFormatProperties(
350
VkPhysicalDevice physicalDevice,
351
VkFormat format,
352
VkImageType type,
353
uint32_t samples,
354
VkImageUsageFlags usage,
355
VkImageTiling tiling,
356
uint32_t* pNumProperties,
357
VkSparseImageFormatProperties* pProperties)
358
{
359
/* Sparse images are not yet supported. */
360
*pNumProperties = 0;
361
}
362
363
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceSparseImageFormatProperties2(
364
VkPhysicalDevice physicalDevice,
365
const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
366
uint32_t *pPropertyCount,
367
VkSparseImageFormatProperties2 *pProperties)
368
{
369
/* Sparse images are not yet supported. */
370
*pPropertyCount = 0;
371
}
372
373
VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceExternalBufferProperties(
374
VkPhysicalDevice physicalDevice,
375
const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
376
VkExternalBufferProperties *pExternalBufferProperties)
377
{
378
pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryProperties) {
379
.externalMemoryFeatures = 0,
380
.exportFromImportedHandleTypes = 0,
381
.compatibleHandleTypes = 0,
382
};
383
}
384
385