lavapipe: VK_EXT_host_image_copy

Acked-by: Konstantin Seurer <konstantin.seurer@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24278>
This commit is contained in:
Mike Blumenkrantz
2023-02-24 14:13:24 -05:00
committed by Marge Bot
parent 6d3009d758
commit 9e9d90c6c3
3 changed files with 192 additions and 0 deletions

View File

@@ -167,6 +167,7 @@ static const struct vk_device_extension_table lvp_device_extensions_supported =
.EXT_extended_dynamic_state3 = true,
.EXT_external_memory_host = true,
.EXT_graphics_pipeline_library = true,
.EXT_host_image_copy = true,
.EXT_host_query_reset = true,
.EXT_image_2d_view_of_3d = true,
.EXT_image_sliced_view_of_3d = true,
@@ -576,6 +577,9 @@ lvp_get_features(const struct lvp_physical_device *pdevice,
.multiviewMeshShader = false,
.primitiveFragmentShadingRateMeshShader = false,
.meshShaderQueries = true,
/* host_image_copy */
.hostImageCopy = true,
};
}
@@ -1109,6 +1113,45 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetPhysicalDeviceProperties2(
properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_PROPERTIES_EXT: {
VkPhysicalDeviceHostImageCopyPropertiesEXT *props =
(VkPhysicalDeviceHostImageCopyPropertiesEXT *)ext;
VkImageLayout layouts[] = {
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_GENERAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_PREINITIALIZED,
VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR,
VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR,
VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR,
VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR,
VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT,
VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR,
};
if (props->copySrcLayoutCount)
typed_memcpy(props->pCopySrcLayouts, layouts, props->copySrcLayoutCount);
props->copySrcLayoutCount = ARRAY_SIZE(layouts);
if (props->copyDstLayoutCount)
typed_memcpy(props->pCopyDstLayouts, layouts, props->copyDstLayoutCount);
props->copyDstLayoutCount = ARRAY_SIZE(layouts);
lvp_device_get_cache_uuid(props->optimalTilingLayoutUUID);
props->identicalMemoryTypeRequirements = VK_FALSE;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =
(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;

View File

@@ -193,6 +193,10 @@ lvp_physical_device_get_format_properties(struct lvp_physical_device *physical_d
out_properties->linearTilingFeatures = features;
out_properties->optimalTilingFeatures = features;
out_properties->bufferFeatures = buffer_features;
if (out_properties->linearTilingFeatures)
out_properties->linearTilingFeatures |= VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT;
if (out_properties->optimalTilingFeatures)
out_properties->optimalTilingFeatures |= VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT;
}

View File

@@ -24,6 +24,7 @@
#include "lvp_private.h"
#include "util/format/u_format.h"
#include "util/u_inlines.h"
#include "util/u_surface.h"
#include "pipe/p_state.h"
static VkResult
@@ -386,6 +387,18 @@ VKAPI_ATTR void VKAPI_CALL lvp_GetImageSubresourceLayout(
}
}
VKAPI_ATTR void VKAPI_CALL lvp_GetImageSubresourceLayout2EXT(
VkDevice _device,
VkImage _image,
const VkImageSubresource2EXT* pSubresource,
VkSubresourceLayout2EXT* pLayout)
{
lvp_GetImageSubresourceLayout(_device, _image, &pSubresource->imageSubresource, &pLayout->subresourceLayout);
VkSubresourceHostMemcpySizeEXT *size = vk_find_struct(pLayout, SUBRESOURCE_HOST_MEMCPY_SIZE_EXT);
if (size)
size->size = pLayout->subresourceLayout.size;
}
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateBuffer(
VkDevice _device,
const VkBufferCreateInfo* pCreateInfo,
@@ -596,3 +609,135 @@ lvp_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
vk_object_base_finish(&view->base);
vk_free2(&device->vk.alloc, pAllocator, view);
}
VKAPI_ATTR VkResult VKAPI_CALL
lvp_CopyMemoryToImageEXT(VkDevice _device, const VkCopyMemoryToImageInfoEXT *pCopyMemoryToImageInfo)
{
LVP_FROM_HANDLE(lvp_device, device, _device);
LVP_FROM_HANDLE(lvp_image, image, pCopyMemoryToImageInfo->dstImage);
for (unsigned i = 0; i < pCopyMemoryToImageInfo->regionCount; i++) {
const VkMemoryToImageCopyEXT *copy = &pCopyMemoryToImageInfo->pRegions[i];
struct pipe_box box = {
.x = copy->imageOffset.x,
.y = copy->imageOffset.y,
.width = copy->imageExtent.width,
.height = copy->imageExtent.height,
.depth = 1,
};
switch (image->bo->target) {
case PIPE_TEXTURE_CUBE:
case PIPE_TEXTURE_CUBE_ARRAY:
case PIPE_TEXTURE_2D_ARRAY:
case PIPE_TEXTURE_1D_ARRAY:
/* these use layer */
box.z = copy->imageSubresource.baseArrayLayer;
box.depth = copy->imageSubresource.layerCount;
break;
case PIPE_TEXTURE_3D:
/* this uses depth */
box.z = copy->imageOffset.z;
box.depth = copy->imageExtent.depth;
break;
default:
break;
}
unsigned stride = util_format_get_stride(image->bo->format, copy->memoryRowLength ? copy->memoryRowLength : box.width);
unsigned layer_stride = util_format_get_2d_size(image->bo->format, stride, copy->memoryImageHeight ? copy->memoryImageHeight : box.height);
device->queue.ctx->texture_subdata(device->queue.ctx, image->bo, copy->imageSubresource.mipLevel, 0,
&box, copy->pHostPointer, stride, layer_stride);
}
return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL
lvp_CopyImageToMemoryEXT(VkDevice _device, const VkCopyImageToMemoryInfoEXT *pCopyImageToMemoryInfo)
{
LVP_FROM_HANDLE(lvp_device, device, _device);
LVP_FROM_HANDLE(lvp_image, image, pCopyImageToMemoryInfo->srcImage);
for (unsigned i = 0; i < pCopyImageToMemoryInfo->regionCount; i++) {
const VkImageToMemoryCopyEXT *copy = &pCopyImageToMemoryInfo->pRegions[i];
struct pipe_box box = {
box.x = copy->imageOffset.x,
box.y = copy->imageOffset.y,
box.width = copy->imageExtent.width,
box.height = copy->imageExtent.height,
.depth = 1,
};
switch (image->bo->target) {
case PIPE_TEXTURE_CUBE:
case PIPE_TEXTURE_CUBE_ARRAY:
case PIPE_TEXTURE_2D_ARRAY:
case PIPE_TEXTURE_1D_ARRAY:
/* these use layer */
box.z = copy->imageSubresource.baseArrayLayer;
box.depth = copy->imageSubresource.layerCount;
break;
case PIPE_TEXTURE_3D:
/* this uses depth */
box.z = copy->imageOffset.z;
box.depth = copy->imageExtent.depth;
break;
default:
break;
}
struct pipe_transfer *xfer;
uint8_t *data = device->queue.ctx->texture_map(device->queue.ctx, image->bo, copy->imageSubresource.mipLevel,
PIPE_MAP_READ | PIPE_MAP_UNSYNCHRONIZED | PIPE_MAP_THREAD_SAFE, &box, &xfer);
if (!data)
return VK_ERROR_MEMORY_MAP_FAILED;
unsigned stride = util_format_get_stride(image->bo->format, copy->memoryRowLength ? copy->memoryRowLength : box.width);
unsigned layer_stride = util_format_get_2d_size(image->bo->format, stride, copy->memoryImageHeight ? copy->memoryImageHeight : box.height);
util_copy_box(copy->pHostPointer, image->bo->format, stride, layer_stride,
/* offsets are all zero because texture_map handles the offset */
0, 0, 0, box.width, box.height, box.depth, data, xfer->stride, xfer->layer_stride, 0, 0, 0);
pipe_texture_unmap(device->queue.ctx, xfer);
}
return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL
lvp_CopyImageToImageEXT(VkDevice _device, const VkCopyImageToImageInfoEXT *pCopyImageToImageInfo)
{
LVP_FROM_HANDLE(lvp_device, device, _device);
LVP_FROM_HANDLE(lvp_image, src_image, pCopyImageToImageInfo->srcImage);
LVP_FROM_HANDLE(lvp_image, dst_image, pCopyImageToImageInfo->dstImage);
/* basically the same as handle_copy_image() */
for (unsigned i = 0; i < pCopyImageToImageInfo->regionCount; i++) {
struct pipe_box src_box;
src_box.x = pCopyImageToImageInfo->pRegions[i].srcOffset.x;
src_box.y = pCopyImageToImageInfo->pRegions[i].srcOffset.y;
src_box.width = pCopyImageToImageInfo->pRegions[i].extent.width;
src_box.height = pCopyImageToImageInfo->pRegions[i].extent.height;
if (src_image->bo->target == PIPE_TEXTURE_3D) {
src_box.depth = pCopyImageToImageInfo->pRegions[i].extent.depth;
src_box.z = pCopyImageToImageInfo->pRegions[i].srcOffset.z;
} else {
src_box.depth = pCopyImageToImageInfo->pRegions[i].srcSubresource.layerCount;
src_box.z = pCopyImageToImageInfo->pRegions[i].srcSubresource.baseArrayLayer;
}
unsigned dstz = dst_image->bo->target == PIPE_TEXTURE_3D ?
pCopyImageToImageInfo->pRegions[i].dstOffset.z :
pCopyImageToImageInfo->pRegions[i].dstSubresource.baseArrayLayer;
device->queue.ctx->resource_copy_region(device->queue.ctx, dst_image->bo,
pCopyImageToImageInfo->pRegions[i].dstSubresource.mipLevel,
pCopyImageToImageInfo->pRegions[i].dstOffset.x,
pCopyImageToImageInfo->pRegions[i].dstOffset.y,
dstz,
src_image->bo,
pCopyImageToImageInfo->pRegions[i].srcSubresource.mipLevel,
&src_box);
}
return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL
lvp_TransitionImageLayoutEXT(VkDevice device, uint32_t transitionCount, const VkHostImageLayoutTransitionInfoEXT *pTransitions)
{
/* no-op */
return VK_SUCCESS;
}