v3dv: implement vkCreateImageView

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
Iago Toral Quiroga 2019-12-05 12:35:02 +01:00 committed by Marge Bot
parent 16ec12b740
commit dee9976200
4 changed files with 246 additions and 0 deletions

View file

@ -71,6 +71,136 @@ v3dv_get_format(VkFormat format)
return NULL;
}
void
v3dv_get_internal_type_bpp_for_output_format(uint32_t format,
uint32_t *type,
uint32_t *bpp)
{
switch (format) {
case V3D_OUTPUT_IMAGE_FORMAT_RGBA8:
case V3D_OUTPUT_IMAGE_FORMAT_RGB8:
case V3D_OUTPUT_IMAGE_FORMAT_RG8:
case V3D_OUTPUT_IMAGE_FORMAT_R8:
case V3D_OUTPUT_IMAGE_FORMAT_ABGR4444:
case V3D_OUTPUT_IMAGE_FORMAT_BGR565:
case V3D_OUTPUT_IMAGE_FORMAT_ABGR1555:
*type = V3D_INTERNAL_TYPE_8;
*bpp = V3D_INTERNAL_BPP_32;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RGBA8I:
case V3D_OUTPUT_IMAGE_FORMAT_RG8I:
case V3D_OUTPUT_IMAGE_FORMAT_R8I:
*type = V3D_INTERNAL_TYPE_8I;
*bpp = V3D_INTERNAL_BPP_32;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RGBA8UI:
case V3D_OUTPUT_IMAGE_FORMAT_RG8UI:
case V3D_OUTPUT_IMAGE_FORMAT_R8UI:
*type = V3D_INTERNAL_TYPE_8UI;
*bpp = V3D_INTERNAL_BPP_32;
break;
case V3D_OUTPUT_IMAGE_FORMAT_SRGB8_ALPHA8:
case V3D_OUTPUT_IMAGE_FORMAT_SRGB:
case V3D_OUTPUT_IMAGE_FORMAT_RGB10_A2:
case V3D_OUTPUT_IMAGE_FORMAT_R11F_G11F_B10F:
case V3D_OUTPUT_IMAGE_FORMAT_RGBA16F:
/* Note that sRGB RTs are stored in the tile buffer at 16F,
* and the conversion to sRGB happens at tilebuffer load/store.
*/
*type = V3D_INTERNAL_TYPE_16F;
*bpp = V3D_INTERNAL_BPP_64;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RG16F:
case V3D_OUTPUT_IMAGE_FORMAT_R16F:
*type = V3D_INTERNAL_TYPE_16F;
/* Use 64bpp to make sure the TLB doesn't throw away the alpha
* channel before alpha test happens.
*/
*bpp = V3D_INTERNAL_BPP_64;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RGBA16I:
*type = V3D_INTERNAL_TYPE_16I;
*bpp = V3D_INTERNAL_BPP_64;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RG16I:
case V3D_OUTPUT_IMAGE_FORMAT_R16I:
*type = V3D_INTERNAL_TYPE_16I;
*bpp = V3D_INTERNAL_BPP_32;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RGB10_A2UI:
case V3D_OUTPUT_IMAGE_FORMAT_RGBA16UI:
*type = V3D_INTERNAL_TYPE_16UI;
*bpp = V3D_INTERNAL_BPP_64;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RG16UI:
case V3D_OUTPUT_IMAGE_FORMAT_R16UI:
*type = V3D_INTERNAL_TYPE_16UI;
*bpp = V3D_INTERNAL_BPP_32;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RGBA32I:
*type = V3D_INTERNAL_TYPE_32I;
*bpp = V3D_INTERNAL_BPP_128;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RG32I:
*type = V3D_INTERNAL_TYPE_32I;
*bpp = V3D_INTERNAL_BPP_64;
break;
case V3D_OUTPUT_IMAGE_FORMAT_R32I:
*type = V3D_INTERNAL_TYPE_32I;
*bpp = V3D_INTERNAL_BPP_32;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RGBA32UI:
*type = V3D_INTERNAL_TYPE_32UI;
*bpp = V3D_INTERNAL_BPP_128;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RG32UI:
*type = V3D_INTERNAL_TYPE_32UI;
*bpp = V3D_INTERNAL_BPP_64;
break;
case V3D_OUTPUT_IMAGE_FORMAT_R32UI:
*type = V3D_INTERNAL_TYPE_32UI;
*bpp = V3D_INTERNAL_BPP_32;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RGBA32F:
*type = V3D_INTERNAL_TYPE_32F;
*bpp = V3D_INTERNAL_BPP_128;
break;
case V3D_OUTPUT_IMAGE_FORMAT_RG32F:
*type = V3D_INTERNAL_TYPE_32F;
*bpp = V3D_INTERNAL_BPP_64;
break;
case V3D_OUTPUT_IMAGE_FORMAT_R32F:
*type = V3D_INTERNAL_TYPE_32F;
*bpp = V3D_INTERNAL_BPP_32;
break;
default:
/* Provide some default values, as we'll be called at RB
* creation time, even if an RB with this format isn't supported.
*/
*type = V3D_INTERNAL_TYPE_8;
*bpp = V3D_INTERNAL_BPP_32;
break;
}
}
static VkFormatFeatureFlags
image_format_features(VkFormat vk_format,
const struct v3dv_format *v3dv_format,

View file

@ -244,6 +244,17 @@ v3d_setup_slices(struct v3dv_image *image)
}
}
static uint32_t
layer_offset(struct v3dv_image *image, uint32_t level, uint32_t layer)
{
struct v3d_resource_slice *slice = &image->slices[level];
if (image->type == VK_IMAGE_TYPE_3D)
return slice->offset + layer * slice->size;
else
return slice->offset + layer * image->cube_map_stride;
}
VkResult
v3dv_CreateImage(VkDevice _device,
const VkImageCreateInfo *pCreateInfo,
@ -297,3 +308,76 @@ v3dv_CreateImage(VkDevice _device,
return VK_SUCCESS;
}
VkResult
v3dv_CreateImageView(VkDevice _device,
const VkImageViewCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkImageView *pView)
{
V3DV_FROM_HANDLE(v3dv_device, device, _device);
V3DV_FROM_HANDLE(v3dv_image, image, pCreateInfo->image);
struct v3dv_image_view *iview;
iview = vk_zalloc2(&device->alloc, pAllocator, sizeof(*iview), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (iview == NULL)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
assert(range->layerCount > 0);
assert(range->baseMipLevel < image->levels);
/* FIXME: we don't handle depth/stencil yet */
assert((range->aspectMask &
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0);
#ifdef DEBUG
switch (image->type) {
case VK_IMAGE_TYPE_1D:
case VK_IMAGE_TYPE_2D:
assert(range->baseArrayLayer + v3dv_layer_count(image, range) - 1 <=
image->array_size);
break;
case VK_IMAGE_TYPE_3D:
assert(range->baseArrayLayer + v3dv_layer_count(image, range) - 1
<= u_minify(image->extent.depth, range->baseMipLevel));
break;
default:
unreachable("bad VkImageType");
}
#endif
iview->image = image;
iview->aspects = range->aspectMask;
iview->extent = (VkExtent3D) {
.width = u_minify(image->extent.width , range->baseMipLevel),
.height = u_minify(image->extent.height, range->baseMipLevel),
.depth = u_minify(image->extent.depth , range->baseMipLevel),
};
iview->first_layer = range->baseArrayLayer;
iview->last_layer = range->baseArrayLayer +
v3dv_layer_count(image, range) - 1;
iview->offset = layer_offset(image, range->baseMipLevel, iview->first_layer);
iview->tiling = image->slices[0].tiling;
iview->vk_format = pCreateInfo->format;
iview->format = v3dv_get_format(pCreateInfo->format);
assert(iview->format && iview->format->supported);
const struct util_format_description *desc =
vk_format_description(iview->vk_format);
iview->swap_rb = desc->swizzle[0] == PIPE_SWIZZLE_Z &&
iview->vk_format != VK_FORMAT_B5G6R5_UNORM_PACK16;
v3dv_get_internal_type_bpp_for_output_format(iview->format->rt_type,
&iview->internal_type,
&iview->internal_bpp);
*pView = v3dv_image_view_to_handle(iview);
return VK_SUCCESS;
}

View file

@ -278,6 +278,23 @@ struct v3dv_image {
VkDeviceSize mem_offset;
};
struct v3dv_image_view {
const struct v3dv_image *image;
VkImageAspectFlags aspects;
VkExtent3D extent;
VkFormat vk_format;
const struct v3dv_format *format;
bool swap_rb;
enum v3d_tiling_mode tiling;
uint32_t internal_bpp;
uint32_t internal_type;
uint32_t first_layer;
uint32_t last_layer;
uint32_t offset;
};
struct v3dv_shader_module {
unsigned char sha1[20];
uint32_t size;
@ -321,6 +338,7 @@ void v3dv_loge(const char *format, ...) v3dv_printflike(1, 2);
void v3dv_loge_v(const char *format, va_list va);
const struct v3dv_format *v3dv_get_format(VkFormat);
void v3dv_get_internal_type_bpp_for_output_format(uint32_t format, uint32_t *type, uint32_t *bpp);
uint32_t v3d_utile_width(int cpp);
uint32_t v3d_utile_height(int cpp);
@ -376,8 +394,16 @@ V3DV_DEFINE_HANDLE_CASTS(v3dv_queue, VkQueue)
V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_device_memory, VkDeviceMemory)
V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_image, VkImage)
V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_image_view, VkImageView)
V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_shader_module, VkShaderModule)
/* This is defined as a macro so that it works for both
* VkImageSubresourceRange and VkImageSubresourceLayers
*/
#define v3dv_layer_count(_image, _range) \
((_range)->layerCount == VK_REMAINING_ARRAY_LAYERS ? \
(_image)->array_size - (_range)->baseArrayLayer : (_range)->layerCount)
static inline int
v3dv_ioctl(int fd, unsigned long request, void *arg)
{

View file

@ -120,4 +120,10 @@ vk_format_get_blockheight(VkFormat format)
return util_format_get_blockheight(vk_format_to_pipe_format(format));
}
static inline const struct util_format_description *
vk_format_description(VkFormat format)
{
return util_format_description(vk_format_to_pipe_format(format));
}
#endif /* VK_FORMAT_INFO_H */