X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fintel%2Fvulkan%2Fanv_image.c;h=63b8c86f5c33c1c82491ec9c4dad3aeb5606ee62;hb=00e79cec995b8c654783860613bc36b90d3d33dc;hp=143a08413f720d3405b802c8b98cd24f0563177e;hpb=3fd308a357b9057447d21c67718d13524dbbb40d;p=mesa.git diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index 143a08413f7..63b8c86f5c3 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -29,6 +29,8 @@ #include "anv_private.h" +#include "vk_format_info.h" + /** * Exactly one bit must be set in \a aspect. */ @@ -118,41 +120,38 @@ make_surface(const struct anv_device *dev, [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D, }; - isl_tiling_flags_t tiling_flags = anv_info->isl_tiling_flags; - if (vk_info->tiling == VK_IMAGE_TILING_LINEAR) - tiling_flags = ISL_TILING_LINEAR_BIT; + /* Translate the Vulkan tiling to an equivalent ISL tiling, then filter the + * result with an optionally provided ISL tiling argument. + */ + isl_tiling_flags_t tiling_flags = + (vk_info->tiling == VK_IMAGE_TILING_LINEAR) ? + ISL_TILING_LINEAR_BIT : ISL_TILING_ANY_MASK; + + if (anv_info->isl_tiling_flags) + tiling_flags &= anv_info->isl_tiling_flags; + + assert(tiling_flags); struct anv_surface *anv_surf = get_surface(image, aspect); - VkExtent3D extent; - switch (vk_info->imageType) { - case VK_IMAGE_TYPE_1D: - extent = (VkExtent3D) { vk_info->extent.width, 1, 1 }; - break; - case VK_IMAGE_TYPE_2D: - extent = (VkExtent3D) { vk_info->extent.width, vk_info->extent.height, 1 }; - break; - case VK_IMAGE_TYPE_3D: - extent = vk_info->extent; - break; - default: - unreachable("invalid image type"); - } + image->extent = anv_sanitize_image_extent(vk_info->imageType, + vk_info->extent); - image->extent = extent; + enum isl_format format = anv_get_isl_format(&dev->info, vk_info->format, + aspect, vk_info->tiling); + assert(format != ISL_FORMAT_UNSUPPORTED); ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl, .dim = vk_to_isl_surf_dim[vk_info->imageType], - .format = anv_get_isl_format(vk_info->format, aspect, - vk_info->tiling, NULL), - .width = extent.width, - .height = extent.height, - .depth = extent.depth, + .format = format, + .width = image->extent.width, + .height = image->extent.height, + .depth = image->extent.depth, .levels = vk_info->mipLevels, .array_len = vk_info->arrayLayers, .samples = vk_info->samples, .min_alignment = 0, - .min_pitch = 0, + .min_pitch = anv_info->stride, .usage = choose_isl_surf_usage(image->usage, aspect), .tiling_flags = tiling_flags); @@ -173,7 +172,7 @@ make_surface(const struct anv_device *dev, */ static VkImageUsageFlags anv_image_get_full_usage(const VkImageCreateInfo *info, - const struct anv_format *format) + VkImageAspectFlags aspects) { VkImageUsageFlags usage = info->usage; @@ -195,7 +194,7 @@ anv_image_get_full_usage(const VkImageCreateInfo *info, */ usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - if (anv_format_is_depth_or_stencil(format)) { + if (aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { /* vkCmdClearDepthStencilImage() only requires that * VK_IMAGE_USAGE_TRANSFER_SRC_BIT be set. In particular, it does * not require VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT. Meta @@ -218,7 +217,6 @@ anv_image_create(VkDevice _device, ANV_FROM_HANDLE(anv_device, device, _device); const VkImageCreateInfo *pCreateInfo = create_info->vk_info; struct anv_image *image = NULL; - const struct anv_format *format = anv_format_for_vk_format(pCreateInfo->format); VkResult r; assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); @@ -239,32 +237,18 @@ anv_image_create(VkDevice _device, image->type = pCreateInfo->imageType; image->extent = pCreateInfo->extent; image->vk_format = pCreateInfo->format; - image->format = format; + image->aspects = vk_format_aspects(image->vk_format); image->levels = pCreateInfo->mipLevels; image->array_size = pCreateInfo->arrayLayers; image->samples = pCreateInfo->samples; - image->usage = anv_image_get_full_usage(pCreateInfo, format); + image->usage = anv_image_get_full_usage(pCreateInfo, image->aspects); image->tiling = pCreateInfo->tiling; - if (likely(anv_format_is_color(format))) { - r = make_surface(device, image, create_info, - VK_IMAGE_ASPECT_COLOR_BIT); + uint32_t b; + for_each_bit(b, image->aspects) { + r = make_surface(device, image, create_info, (1 << b)); if (r != VK_SUCCESS) goto fail; - } else { - if (image->format->has_depth) { - r = make_surface(device, image, create_info, - VK_IMAGE_ASPECT_DEPTH_BIT); - if (r != VK_SUCCESS) - goto fail; - } - - if (image->format->has_stencil) { - r = make_surface(device, image, create_info, - VK_IMAGE_ASPECT_STENCIL_BIT); - if (r != VK_SUCCESS) - goto fail; - } } *pImage = anv_image_to_handle(image); @@ -287,7 +271,6 @@ anv_CreateImage(VkDevice device, return anv_image_create(device, &(struct anv_image_create_info) { .vk_info = pCreateInfo, - .isl_tiling_flags = ISL_TILING_ANY_MASK, }, pAllocator, pImage); @@ -349,84 +332,6 @@ void anv_GetImageSubresourceLayout( } } -VkResult -anv_validate_CreateImageView(VkDevice _device, - const VkImageViewCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VkImageView *pView) -{ - ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image); - const VkImageSubresourceRange *subresource; - const struct anv_format *view_format_info; - - /* Validate structure type before dereferencing it. */ - assert(pCreateInfo); - assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO); - subresource = &pCreateInfo->subresourceRange; - - /* Validate viewType is in range before using it. */ - assert(pCreateInfo->viewType >= VK_IMAGE_VIEW_TYPE_BEGIN_RANGE); - assert(pCreateInfo->viewType <= VK_IMAGE_VIEW_TYPE_END_RANGE); - - /* Validate format is in range before using it. */ - assert(pCreateInfo->format >= VK_FORMAT_BEGIN_RANGE); - assert(pCreateInfo->format <= VK_FORMAT_END_RANGE); - view_format_info = anv_format_for_vk_format(pCreateInfo->format); - - /* Validate channel swizzles. */ - assert(pCreateInfo->components.r >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE); - assert(pCreateInfo->components.r <= VK_COMPONENT_SWIZZLE_END_RANGE); - assert(pCreateInfo->components.g >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE); - assert(pCreateInfo->components.g <= VK_COMPONENT_SWIZZLE_END_RANGE); - assert(pCreateInfo->components.b >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE); - assert(pCreateInfo->components.b <= VK_COMPONENT_SWIZZLE_END_RANGE); - assert(pCreateInfo->components.a >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE); - assert(pCreateInfo->components.a <= VK_COMPONENT_SWIZZLE_END_RANGE); - - /* Validate subresource. */ - assert(subresource->aspectMask != 0); - assert(subresource->levelCount > 0); - assert(subresource->layerCount > 0); - assert(subresource->baseMipLevel < image->levels); - assert(subresource->baseMipLevel + anv_get_levelCount(image, subresource) <= image->levels); - assert(subresource->baseArrayLayer < image->array_size); - assert(subresource->baseArrayLayer + anv_get_layerCount(image, subresource) <= image->array_size); - assert(pView); - - const VkImageAspectFlags ds_flags = VK_IMAGE_ASPECT_DEPTH_BIT - | VK_IMAGE_ASPECT_STENCIL_BIT; - - /* Validate format. */ - if (subresource->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { - assert(subresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); - assert(!image->format->has_depth); - assert(!image->format->has_stencil); - assert(!view_format_info->has_depth); - assert(!view_format_info->has_stencil); - assert(view_format_info->isl_layout->bs == - image->format->isl_layout->bs); - } else if (subresource->aspectMask & ds_flags) { - assert((subresource->aspectMask & ~ds_flags) == 0); - - if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) { - assert(image->format->has_depth); - assert(view_format_info->has_depth); - assert(view_format_info->isl_layout->bs == - image->format->isl_layout->bs); - } - - if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) { - /* FINISHME: Is it legal to have an R8 view of S8? */ - assert(image->format->has_stencil); - assert(view_format_info->has_stencil); - } - } else { - assert(!"bad VkImageSubresourceRange::aspectFlags"); - } - - return anv_CreateImageView(_device, pCreateInfo, pAllocator, pView); -} - static struct anv_state alloc_surface_state(struct anv_device *device, struct anv_cmd_buffer *cmd_buffer) @@ -438,36 +343,20 @@ alloc_surface_state(struct anv_device *device, } } -static bool -has_matching_storage_typed_format(const struct anv_device *device, - enum isl_format format) -{ - return (isl_format_get_layout(format)->bs <= 4 || - (isl_format_get_layout(format)->bs <= 8 && - (device->info.gen >= 8 || device->info.is_haswell)) || - device->info.gen >= 9); -} - static enum isl_channel_select remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component, - struct anv_format_swizzle format_swizzle) + struct isl_swizzle format_swizzle) { if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY) swizzle = component; switch (swizzle) { - case VK_COMPONENT_SWIZZLE_ZERO: - return ISL_CHANNEL_SELECT_ZERO; - case VK_COMPONENT_SWIZZLE_ONE: - return ISL_CHANNEL_SELECT_ONE; - case VK_COMPONENT_SWIZZLE_R: - return ISL_CHANNEL_SELECT_RED + format_swizzle.r; - case VK_COMPONENT_SWIZZLE_G: - return ISL_CHANNEL_SELECT_RED + format_swizzle.g; - case VK_COMPONENT_SWIZZLE_B: - return ISL_CHANNEL_SELECT_RED + format_swizzle.b; - case VK_COMPONENT_SWIZZLE_A: - return ISL_CHANNEL_SELECT_RED + format_swizzle.a; + case VK_COMPONENT_SWIZZLE_ZERO: return ISL_CHANNEL_SELECT_ZERO; + case VK_COMPONENT_SWIZZLE_ONE: return ISL_CHANNEL_SELECT_ONE; + case VK_COMPONENT_SWIZZLE_R: return format_swizzle.r; + case VK_COMPONENT_SWIZZLE_G: return format_swizzle.g; + case VK_COMPONENT_SWIZZLE_B: return format_swizzle.b; + case VK_COMPONENT_SWIZZLE_A: return format_swizzle.a; default: unreachable("Invalid swizzle"); } @@ -478,7 +367,6 @@ anv_image_view_init(struct anv_image_view *iview, struct anv_device *device, const VkImageViewCreateInfo* pCreateInfo, struct anv_cmd_buffer *cmd_buffer, - uint32_t offset, VkImageUsageFlags usage_mask) { ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image); @@ -509,34 +397,32 @@ anv_image_view_init(struct anv_image_view *iview, iview->image = image; iview->bo = image->bo; - iview->offset = image->offset + surface->offset + offset; + iview->offset = image->offset + surface->offset; iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask; iview->vk_format = pCreateInfo->format; - struct anv_format_swizzle swizzle; - enum isl_format format = anv_get_isl_format(pCreateInfo->format, - range->aspectMask, - image->tiling, &swizzle); + struct anv_format format = anv_get_format(&device->info, pCreateInfo->format, + range->aspectMask, image->tiling); iview->base_layer = range->baseArrayLayer; iview->base_mip = range->baseMipLevel; struct isl_view isl_view = { - .format = format, + .format = format.isl_format, .base_level = range->baseMipLevel, .levels = anv_get_levelCount(image, range), .base_array_layer = range->baseArrayLayer, .array_len = anv_get_layerCount(image, range), - .channel_select = { - remap_swizzle(pCreateInfo->components.r, - VK_COMPONENT_SWIZZLE_R, swizzle), - remap_swizzle(pCreateInfo->components.g, - VK_COMPONENT_SWIZZLE_G, swizzle), - remap_swizzle(pCreateInfo->components.b, - VK_COMPONENT_SWIZZLE_B, swizzle), - remap_swizzle(pCreateInfo->components.a, - VK_COMPONENT_SWIZZLE_A, swizzle), + .swizzle = { + .r = remap_swizzle(pCreateInfo->components.r, + VK_COMPONENT_SWIZZLE_R, format.swizzle), + .g = remap_swizzle(pCreateInfo->components.g, + VK_COMPONENT_SWIZZLE_G, format.swizzle), + .b = remap_swizzle(pCreateInfo->components.b, + VK_COMPONENT_SWIZZLE_B, format.swizzle), + .a = remap_swizzle(pCreateInfo->components.a, + VK_COMPONENT_SWIZZLE_A, format.swizzle), }, }; @@ -570,7 +456,18 @@ anv_image_view_init(struct anv_image_view *iview, iview->sampler_surface_state.alloc_size = 0; } - if (image->usage & usage_mask & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { + /* This is kind-of hackish. It is possible, due to get_full_usage above, + * to get a surface state with a non-renderable format but with + * VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT. This happens in particular for + * formats which aren't renderable but where we want to use Vulkan copy + * commands so VK_IMAGE_USAGE_TRANSFER_DST_BIT is set. In the case of a + * copy, meta will use a format that we can render to, but most of the rest + * of the time, we don't want to create those surface states. Once we + * start using blorp for copies, this problem will go away and we can + * remove a lot of hacks. + */ + if ((image->usage & usage_mask & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && + isl_format_supports_rendering(&device->info, isl_view.format)) { iview->color_rt_surface_state = alloc_surface_state(device, cmd_buffer); isl_view.usage = cube_usage | ISL_SURF_USAGE_RENDER_TARGET_BIT; @@ -586,11 +483,15 @@ anv_image_view_init(struct anv_image_view *iview, iview->color_rt_surface_state.alloc_size = 0; } + /* NOTE: This one needs to go last since it may stomp isl_view.format */ if (image->usage & usage_mask & VK_IMAGE_USAGE_STORAGE_BIT) { iview->storage_surface_state = alloc_surface_state(device, cmd_buffer); - if (has_matching_storage_typed_format(device, format)) { + if (isl_has_matching_typed_storage_image_format(&device->info, + format.isl_format)) { isl_view.usage = cube_usage | ISL_SURF_USAGE_STORAGE_BIT; + isl_view.format = isl_lower_storage_image_format(&device->info, + isl_view.format); isl_surf_fill_state(&device->isl_dev, iview->storage_surface_state.map, .surf = &surface->isl, @@ -628,7 +529,7 @@ anv_CreateImageView(VkDevice _device, if (view == NULL) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - anv_image_view_init(view, device, pCreateInfo, NULL, 0, ~0); + anv_image_view_init(view, device, pCreateInfo, NULL, ~0); *pView = anv_image_view_to_handle(view); @@ -660,56 +561,50 @@ anv_DestroyImageView(VkDevice _device, VkImageView _iview, anv_free2(&device->alloc, pAllocator, iview); } -VkResult -anv_CreateBufferView(VkDevice _device, - const VkBufferViewCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VkBufferView *pView) + +void anv_buffer_view_init(struct anv_buffer_view *view, + struct anv_device *device, + const VkBufferViewCreateInfo* pCreateInfo, + struct anv_cmd_buffer *cmd_buffer) { - ANV_FROM_HANDLE(anv_device, device, _device); ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer); - struct anv_buffer_view *view; - - view = anv_alloc2(&device->alloc, pAllocator, sizeof(*view), 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (!view) - return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - const struct anv_format *format = - anv_format_for_vk_format(pCreateInfo->format); + /* TODO: Handle the format swizzle? */ - view->format = format->isl_format; + view->format = anv_get_isl_format(&device->info, pCreateInfo->format, + VK_IMAGE_ASPECT_COLOR_BIT, + VK_IMAGE_TILING_LINEAR); + const uint32_t format_bs = isl_format_get_layout(view->format)->bpb / 8; view->bo = buffer->bo; view->offset = buffer->offset + pCreateInfo->offset; view->range = pCreateInfo->range == VK_WHOLE_SIZE ? - buffer->size - view->offset : pCreateInfo->range; + buffer->size - pCreateInfo->offset : pCreateInfo->range; + view->range = align_down_npot_u32(view->range, format_bs); if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) { - view->surface_state = - anv_state_pool_alloc(&device->surface_state_pool, 64, 64); + view->surface_state = alloc_surface_state(device, cmd_buffer); anv_fill_buffer_surface_state(device, view->surface_state, view->format, - view->offset, view->range, - format->isl_layout->bs); + view->offset, view->range, format_bs); } else { view->surface_state = (struct anv_state){ 0 }; } if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) { - view->storage_surface_state = - anv_state_pool_alloc(&device->surface_state_pool, 64, 64); + view->storage_surface_state = alloc_surface_state(device, cmd_buffer); enum isl_format storage_format = - has_matching_storage_typed_format(device, view->format) ? - isl_lower_storage_image_format(&device->isl_dev, view->format) : + isl_has_matching_typed_storage_image_format(&device->info, + view->format) ? + isl_lower_storage_image_format(&device->info, view->format) : ISL_FORMAT_RAW; anv_fill_buffer_surface_state(device, view->storage_surface_state, storage_format, view->offset, view->range, (storage_format == ISL_FORMAT_RAW ? 1 : - format->isl_layout->bs)); + isl_format_get_layout(storage_format)->bpb / 8)); isl_buffer_fill_image_param(&device->isl_dev, &view->storage_image_param, @@ -717,6 +612,23 @@ anv_CreateBufferView(VkDevice _device, } else { view->storage_surface_state = (struct anv_state){ 0 }; } +} + +VkResult +anv_CreateBufferView(VkDevice _device, + const VkBufferViewCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkBufferView *pView) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_buffer_view *view; + + view = anv_alloc2(&device->alloc, pAllocator, sizeof(*view), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!view) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + anv_buffer_view_init(view, device, pCreateInfo, NULL); *pView = anv_buffer_view_to_handle(view); @@ -751,42 +663,39 @@ anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlag * Meta attaches all destination surfaces as color render targets. Guess * what surface the Meta Dragons really want. */ - if (image->format->has_depth && image->format->has_stencil) { - return &image->depth_surface; - } else if (image->format->has_depth) { + if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { return &image->depth_surface; - } else if (image->format->has_stencil) { + } else if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { return &image->stencil_surface; } else { + assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); return &image->color_surface; } break; case VK_IMAGE_ASPECT_DEPTH_BIT: - assert(image->format->has_depth); + assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT); return &image->depth_surface; case VK_IMAGE_ASPECT_STENCIL_BIT: - assert(image->format->has_stencil); + assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT); return &image->stencil_surface; case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT: - if (image->format->has_depth && image->format->has_stencil) { - /* FINISHME: The Vulkan spec (git a511ba2) requires support for - * combined depth stencil formats. Specifically, it states: - * - * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or - * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported. - * - * Image views with both depth and stencil aspects are only valid for - * render target attachments, in which case - * cmd_buffer_emit_depth_stencil() will pick out both the depth and - * stencil surfaces from the underlying surface. - */ - return &image->depth_surface; - } else if (image->format->has_depth) { + /* FINISHME: The Vulkan spec (git a511ba2) requires support for + * combined depth stencil formats. Specifically, it states: + * + * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or + * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported. + * + * Image views with both depth and stencil aspects are only valid for + * render target attachments, in which case + * cmd_buffer_emit_depth_stencil() will pick out both the depth and + * stencil surfaces from the underlying surface. + */ + if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { return &image->depth_surface; - } else if (image->format->has_stencil) { + } else { + assert(image->aspects == VK_IMAGE_ASPECT_STENCIL_BIT); return &image->stencil_surface; } - /* fallthrough */ default: unreachable("image does not have aspect"); return NULL;