2023-01-30 20:11:46 -06:00
|
|
|
#include "nvk_image.h"
|
|
|
|
|
|
|
|
#include "nvk_device.h"
|
2022-06-06 03:26:54 +02:00
|
|
|
#include "nvk_device_memory.h"
|
2022-06-07 19:11:00 +02:00
|
|
|
#include "nvk_format.h"
|
2022-06-06 03:26:54 +02:00
|
|
|
#include "nvk_physical_device.h"
|
|
|
|
|
2023-01-30 20:11:50 -06:00
|
|
|
#include "nil_format.h"
|
|
|
|
#include "vulkan/util/vk_format.h"
|
|
|
|
|
|
|
|
static bool
|
|
|
|
is_storage_image_format(enum pipe_format p_format)
|
|
|
|
{
|
|
|
|
/* TODO: This shouldn't be a fixed list */
|
|
|
|
|
|
|
|
switch (p_format) {
|
|
|
|
case PIPE_FORMAT_R32G32B32A32_UINT:
|
|
|
|
case PIPE_FORMAT_R32G32B32A32_SINT:
|
|
|
|
case PIPE_FORMAT_R32G32B32A32_FLOAT:
|
|
|
|
case PIPE_FORMAT_R32_UINT:
|
|
|
|
case PIPE_FORMAT_R32_SINT:
|
|
|
|
case PIPE_FORMAT_R32_FLOAT:
|
|
|
|
case PIPE_FORMAT_R16G16B16A16_UINT:
|
|
|
|
case PIPE_FORMAT_R16G16B16A16_SINT:
|
|
|
|
case PIPE_FORMAT_R16G16B16A16_FLOAT:
|
|
|
|
case PIPE_FORMAT_R32G32_UINT:
|
|
|
|
case PIPE_FORMAT_R32G32_SINT:
|
|
|
|
case PIPE_FORMAT_R32G32_FLOAT:
|
|
|
|
case PIPE_FORMAT_R8G8B8A8_UINT:
|
|
|
|
case PIPE_FORMAT_R8G8B8A8_SINT:
|
|
|
|
case PIPE_FORMAT_R16G16_UINT:
|
|
|
|
case PIPE_FORMAT_R16G16_SINT:
|
|
|
|
case PIPE_FORMAT_R16G16_FLOAT:
|
|
|
|
case PIPE_FORMAT_R8G8_UINT:
|
|
|
|
case PIPE_FORMAT_R8G8_SINT:
|
|
|
|
case PIPE_FORMAT_R16_UINT:
|
|
|
|
case PIPE_FORMAT_R16_FLOAT:
|
|
|
|
case PIPE_FORMAT_R16_SINT:
|
|
|
|
case PIPE_FORMAT_R8_UINT:
|
|
|
|
case PIPE_FORMAT_R8_SINT:
|
|
|
|
case PIPE_FORMAT_R10G10B10A2_UINT:
|
|
|
|
case PIPE_FORMAT_R10G10B10A2_UNORM:
|
|
|
|
case PIPE_FORMAT_R11G11B10_FLOAT:
|
|
|
|
case PIPE_FORMAT_R16G16B16A16_UNORM:
|
|
|
|
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
|
|
|
case PIPE_FORMAT_R8G8B8A8_UNORM:
|
|
|
|
case PIPE_FORMAT_R8G8B8A8_SNORM:
|
|
|
|
case PIPE_FORMAT_R16G16_UNORM:
|
|
|
|
case PIPE_FORMAT_R16G16_SNORM:
|
|
|
|
case PIPE_FORMAT_R8G8_UNORM:
|
|
|
|
case PIPE_FORMAT_R8G8_SNORM:
|
|
|
|
case PIPE_FORMAT_R16_UNORM:
|
|
|
|
case PIPE_FORMAT_R16_SNORM:
|
|
|
|
case PIPE_FORMAT_R8_UNORM:
|
|
|
|
case PIPE_FORMAT_R8_SNORM:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VkFormatFeatureFlags2
|
|
|
|
nvk_get_image_format_features(struct nvk_physical_device *pdevice,
|
|
|
|
VkFormat vk_format, VkImageTiling tiling)
|
|
|
|
{
|
|
|
|
VkFormatFeatureFlags2 features = 0;
|
|
|
|
|
|
|
|
if (tiling != VK_IMAGE_TILING_OPTIMAL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
enum pipe_format p_format = vk_format_to_pipe_format(vk_format);
|
|
|
|
if (p_format == PIPE_FORMAT_NONE)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
const struct nil_tic_format *tic_format = nil_tic_format_for_pipe(p_format);
|
|
|
|
if (tic_format == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
features |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT;
|
|
|
|
features |= VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
|
|
|
|
features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT;
|
|
|
|
|
|
|
|
if (util_format_is_float(p_format) ||
|
|
|
|
util_format_is_unorm(p_format) ||
|
|
|
|
util_format_is_snorm(p_format))
|
|
|
|
features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
|
|
|
|
|
|
|
|
if (is_storage_image_format(p_format)) {
|
|
|
|
features |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT |
|
|
|
|
VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT |
|
|
|
|
VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (p_format == PIPE_FORMAT_R32_UINT)
|
|
|
|
features |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT;
|
|
|
|
|
|
|
|
const struct nvk_format *nvk_format = nvk_get_format(vk_format);
|
|
|
|
if (nvk_format && nvk_format->supports_2d_blit) {
|
|
|
|
features |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT |
|
|
|
|
VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return features;
|
|
|
|
}
|
|
|
|
|
2023-01-30 20:11:49 -06:00
|
|
|
static enum nil_image_dim
|
|
|
|
vk_image_type_to_nil_dim(VkImageType type)
|
2022-06-06 03:26:54 +02:00
|
|
|
{
|
2023-01-30 20:11:49 -06:00
|
|
|
switch (type) {
|
|
|
|
case VK_IMAGE_TYPE_1D: return NIL_IMAGE_DIM_1D;
|
|
|
|
case VK_IMAGE_TYPE_2D: return NIL_IMAGE_DIM_2D;
|
|
|
|
case VK_IMAGE_TYPE_3D: return NIL_IMAGE_DIM_3D;
|
2022-06-06 03:26:54 +02:00
|
|
|
default:
|
2023-01-30 20:11:49 -06:00
|
|
|
unreachable("Invalid image type");
|
2022-06-06 03:26:54 +02:00
|
|
|
}
|
|
|
|
}
|
2023-01-30 20:11:46 -06:00
|
|
|
|
|
|
|
static VkResult nvk_image_init(struct nvk_device *device,
|
|
|
|
struct nvk_image *image,
|
|
|
|
const VkImageCreateInfo *pCreateInfo)
|
|
|
|
{
|
|
|
|
vk_image_init(&device->vk, &image->vk, pCreateInfo);
|
2022-06-06 03:26:54 +02:00
|
|
|
|
2023-01-30 20:11:49 -06:00
|
|
|
struct nil_image_init_info nil_info = {
|
|
|
|
.dim = vk_image_type_to_nil_dim(pCreateInfo->imageType),
|
|
|
|
.format = vk_format_to_pipe_format(pCreateInfo->format),
|
|
|
|
.extent_px = {
|
|
|
|
.w = pCreateInfo->extent.width,
|
|
|
|
.h = pCreateInfo->extent.height,
|
|
|
|
.d = pCreateInfo->extent.depth,
|
|
|
|
.a = pCreateInfo->arrayLayers,
|
|
|
|
},
|
|
|
|
.levels = pCreateInfo->mipLevels,
|
|
|
|
.samples = pCreateInfo->samples,
|
|
|
|
};
|
|
|
|
|
|
|
|
ASSERTED bool ok = nil_image_init(nvk_device_physical(device)->dev,
|
|
|
|
&image->nil, &nil_info);
|
|
|
|
assert(ok);
|
2022-06-06 03:26:54 +02:00
|
|
|
|
2023-01-30 20:11:46 -06:00
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void nvk_image_finish(struct nvk_image *image)
|
|
|
|
{
|
|
|
|
vk_image_finish(&image->vk);
|
|
|
|
}
|
|
|
|
|
2023-01-30 20:11:49 -06:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
nvk_CreateImage(VkDevice _device,
|
|
|
|
const VkImageCreateInfo *pCreateInfo,
|
|
|
|
const VkAllocationCallbacks *pAllocator,
|
|
|
|
VkImage *pImage)
|
2023-01-30 20:11:46 -06:00
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(nvk_device, device, _device);
|
|
|
|
struct nvk_image *image;
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
image = vk_zalloc2(
|
|
|
|
&device->vk.alloc, pAllocator, sizeof(*image), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
|
|
if (!image)
|
|
|
|
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
|
|
result = nvk_image_init(device, image, pCreateInfo);
|
|
|
|
if (result != VK_SUCCESS) {
|
|
|
|
vk_free2(&device->vk.alloc, pAllocator, image);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pImage = nvk_image_to_handle(image);
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2023-01-30 20:11:49 -06:00
|
|
|
VKAPI_ATTR void VKAPI_CALL
|
|
|
|
nvk_DestroyImage(VkDevice _device,
|
|
|
|
VkImage _image,
|
|
|
|
const VkAllocationCallbacks *pAllocator)
|
2023-01-30 20:11:46 -06:00
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(nvk_device, device, _device);
|
|
|
|
VK_FROM_HANDLE(nvk_image, image, _image);
|
|
|
|
|
|
|
|
if (!image)
|
|
|
|
return;
|
|
|
|
|
|
|
|
nvk_image_finish(image);
|
|
|
|
vk_free2(&device->vk.alloc, pAllocator, image);
|
|
|
|
}
|
2022-05-20 15:27:09 +02:00
|
|
|
|
2023-01-30 20:11:49 -06:00
|
|
|
VKAPI_ATTR void VKAPI_CALL
|
|
|
|
nvk_GetImageMemoryRequirements2(VkDevice _device,
|
|
|
|
const VkImageMemoryRequirementsInfo2 *pInfo,
|
|
|
|
VkMemoryRequirements2 *pMemoryRequirements)
|
2022-05-20 15:27:09 +02:00
|
|
|
{
|
2022-06-06 03:26:54 +02:00
|
|
|
VK_FROM_HANDLE(nvk_device, device, _device);
|
|
|
|
VK_FROM_HANDLE(nvk_image, image, pInfo->image);
|
|
|
|
|
|
|
|
uint32_t memory_types = (1 << device->pdev->mem_type_cnt) - 1;
|
|
|
|
|
|
|
|
// TODO hope for the best?
|
|
|
|
pMemoryRequirements->memoryRequirements.memoryTypeBits = memory_types;
|
|
|
|
pMemoryRequirements->memoryRequirements.alignment = 0x1000;
|
2023-01-30 20:11:49 -06:00
|
|
|
pMemoryRequirements->memoryRequirements.size = image->nil.size_B;
|
2022-06-06 03:26:54 +02:00
|
|
|
|
2022-05-20 15:27:09 +02:00
|
|
|
vk_foreach_struct_const(ext, pInfo->pNext) {
|
|
|
|
switch (ext->sType) {
|
|
|
|
default:
|
|
|
|
nvk_debug_ignored_stype(ext->sType);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-06-06 03:26:54 +02:00
|
|
|
|
2023-08-03 16:10:59 -05:00
|
|
|
VKAPI_ATTR void VKAPI_CALL
|
|
|
|
nvk_GetImageSubresourceLayout(VkDevice device,
|
|
|
|
VkImage _image,
|
|
|
|
const VkImageSubresource *pSubresource,
|
|
|
|
VkSubresourceLayout *pLayout)
|
|
|
|
{
|
|
|
|
VK_FROM_HANDLE(nvk_image, image, _image);
|
|
|
|
|
|
|
|
*pLayout = (VkSubresourceLayout) {
|
|
|
|
.offset = nil_image_level_layer_offset_B(&image->nil,
|
|
|
|
pSubresource->mipLevel,
|
|
|
|
pSubresource->arrayLayer),
|
|
|
|
.size = nil_image_level_size_B(&image->nil, pSubresource->mipLevel),
|
|
|
|
.rowPitch = image->nil.levels[pSubresource->mipLevel].row_stride_B,
|
|
|
|
.arrayPitch = image->nil.array_stride_B,
|
|
|
|
.depthPitch = nil_image_level_depth_stride_B(&image->nil,
|
|
|
|
pSubresource->mipLevel),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-06-06 03:26:54 +02:00
|
|
|
VKAPI_ATTR VkResult VKAPI_CALL
|
2023-01-30 20:11:49 -06:00
|
|
|
nvk_BindImageMemory2(VkDevice _device,
|
|
|
|
uint32_t bindInfoCount,
|
|
|
|
const VkBindImageMemoryInfo *pBindInfos)
|
2022-06-06 03:26:54 +02:00
|
|
|
{
|
|
|
|
for (uint32_t i = 0; i < bindInfoCount; ++i) {
|
|
|
|
VK_FROM_HANDLE(nvk_device_memory, mem, pBindInfos[i].memory);
|
|
|
|
VK_FROM_HANDLE(nvk_image, image, pBindInfos[i].image);
|
|
|
|
|
|
|
|
image->mem = mem;
|
|
|
|
image->offset = pBindInfos[i].memoryOffset;
|
|
|
|
}
|
|
|
|
return VK_SUCCESS;
|
|
|
|
}
|