mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 09:18:04 +02:00
anv: implement EXT_descriptor_heap entry points
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39478>
This commit is contained in:
parent
624dd006f4
commit
9231204026
6 changed files with 386 additions and 1 deletions
|
|
@ -1234,7 +1234,16 @@ anv_state_reserved_array_pool_free(struct anv_state_reserved_array_pool *pool,
|
|||
simple_mtx_lock(&pool->mutex);
|
||||
BITSET_SET(pool->states, idx);
|
||||
simple_mtx_unlock(&pool->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
anv_state_reserved_array_pool_index_free(struct anv_state_reserved_array_pool *pool,
|
||||
uint32_t index)
|
||||
{
|
||||
simple_mtx_lock(&pool->mutex);
|
||||
BITSET_SET(pool->states, index);
|
||||
simple_mtx_unlock(&pool->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
anv_bo_pool_init(struct anv_bo_pool *pool, struct anv_device *device,
|
||||
|
|
|
|||
|
|
@ -2919,3 +2919,250 @@ void anv_GetDescriptorEXT(
|
|||
UNREACHABLE("Invalid descriptor type");
|
||||
}
|
||||
}
|
||||
|
||||
VkResult anv_WriteSamplerDescriptorsEXT(
|
||||
VkDevice _device,
|
||||
uint32_t samplerCount,
|
||||
const VkSamplerCreateInfo* pSamplers,
|
||||
const VkHostAddressRangeEXT* pDescriptors)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_device, device, _device);
|
||||
|
||||
const uint32_t border_color_stride = 64;
|
||||
for (uint32_t i = 0; i < samplerCount; i++) {
|
||||
struct vk_sampler_state vk_state;
|
||||
vk_sampler_state_init(&vk_state, &pSamplers[i]);
|
||||
|
||||
const VkSamplerCustomBorderColorIndexCreateInfoEXT *color_info =
|
||||
vk_find_struct_const(pSamplers[i].pNext,
|
||||
SAMPLER_CUSTOM_BORDER_COLOR_INDEX_CREATE_INFO_EXT);
|
||||
const uint32_t border_color_offset =
|
||||
vk_state.border_color <= VK_BORDER_COLOR_INT_OPAQUE_WHITE ?
|
||||
(device->border_colors.offset + vk_state.border_color * border_color_stride) :
|
||||
(device->custom_border_colors.state.offset + color_info->index * border_color_stride);
|
||||
|
||||
struct anv_sampler_state state;
|
||||
anv_genX(device->info, emit_sampler_state)(device, &vk_state,
|
||||
border_color_offset,
|
||||
&state);
|
||||
|
||||
memcpy(pDescriptors[i].address, state.state[0], ANV_SAMPLER_STATE_SIZE);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static bool
|
||||
texel_info_is_null(const VkTexelBufferDescriptorInfoEXT *texel_info)
|
||||
{
|
||||
return texel_info == NULL ||
|
||||
texel_info->addressRange.size == 0 ||
|
||||
texel_info->addressRange.address == 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
address_range_is_null(const VkDeviceAddressRangeEXT *addr)
|
||||
{
|
||||
return addr == NULL || addr->size == 0 || addr->address == 0;
|
||||
}
|
||||
|
||||
static enum isl_channel_select
|
||||
remap_swizzle(VkComponentSwizzle swizzle,
|
||||
struct isl_swizzle format_swizzle)
|
||||
{
|
||||
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 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");
|
||||
}
|
||||
}
|
||||
|
||||
VkResult anv_WriteResourceDescriptorsEXT(
|
||||
VkDevice _device,
|
||||
uint32_t resourceCount,
|
||||
const VkResourceDescriptorInfoEXT* pResources,
|
||||
const VkHostAddressRangeEXT* pDescriptors)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_device, device, _device);
|
||||
|
||||
for (uint32_t i = 0; i < resourceCount; i++) {
|
||||
const VkResourceDescriptorInfoEXT *res = &pResources[i];
|
||||
const VkHostAddressRangeEXT *out = &pDescriptors[i];
|
||||
|
||||
switch (res->type) {
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
|
||||
const VkImageDescriptorInfoEXT *img_info =
|
||||
res->data.pImage;
|
||||
if (img_info) {
|
||||
ANV_FROM_HANDLE(anv_image, image, img_info->pView->image);
|
||||
|
||||
struct vk_image_view vk_view;
|
||||
vk_image_view_init(&device->vk, &vk_view, img_info->pView);
|
||||
|
||||
VkFormat view_format = vk_view.view_format;
|
||||
if (anv_is_compressed_format_emulated(device->physical,
|
||||
view_format)) {
|
||||
assert(image->emu_plane_format != VK_FORMAT_UNDEFINED);
|
||||
view_format = anv_get_compressed_format_emulation(
|
||||
device->physical, view_format);
|
||||
}
|
||||
|
||||
anv_foreach_image_aspect_bit(iaspect_bit, image, vk_view.aspects) {
|
||||
VkImageAspectFlags aspect = 1u << iaspect_bit;
|
||||
|
||||
const uint32_t vplane = anv_aspect_to_plane(vk_view.aspects, aspect);
|
||||
|
||||
const struct anv_format_plane format = anv_get_format_plane(
|
||||
device->physical, view_format, vplane, image->vk.tiling);
|
||||
|
||||
struct isl_view isl_view = {
|
||||
.format = format.isl_format,
|
||||
.base_level = vk_view.base_mip_level,
|
||||
.levels = vk_view.level_count,
|
||||
.base_array_layer = vk_view.base_array_layer,
|
||||
.array_len = vk_view.layer_count,
|
||||
.min_lod_clamp = vk_view.min_lod,
|
||||
.swizzle = {
|
||||
.r = remap_swizzle(vk_view.swizzle.r, format.swizzle),
|
||||
.g = remap_swizzle(vk_view.swizzle.g, format.swizzle),
|
||||
.b = remap_swizzle(vk_view.swizzle.b, format.swizzle),
|
||||
.a = remap_swizzle(vk_view.swizzle.a, format.swizzle),
|
||||
},
|
||||
};
|
||||
|
||||
if (vk_view.view_type == VK_IMAGE_VIEW_TYPE_3D) {
|
||||
isl_view.base_array_layer = 0;
|
||||
isl_view.array_len = vk_view.extent.depth;
|
||||
}
|
||||
|
||||
if (vk_view.view_type == VK_IMAGE_VIEW_TYPE_CUBE ||
|
||||
vk_view.view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
|
||||
isl_view.usage = ISL_SURF_USAGE_CUBE_BIT;
|
||||
} else {
|
||||
isl_view.usage = 0;
|
||||
}
|
||||
|
||||
const bool is_storage =
|
||||
res->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||
const bool read_only_layout =
|
||||
img_info->layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ||
|
||||
img_info->layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL ||
|
||||
img_info->layout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL ||
|
||||
img_info->layout == VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL;
|
||||
|
||||
enum isl_aux_usage aux_usage =
|
||||
anv_layout_to_aux_usage(device->info, image, aspect,
|
||||
is_storage ?
|
||||
VK_IMAGE_USAGE_STORAGE_BIT :
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
img_info->layout,
|
||||
VK_QUEUE_GRAPHICS_BIT |
|
||||
VK_QUEUE_COMPUTE_BIT);
|
||||
|
||||
struct anv_surface_state state = {};
|
||||
anv_image_fill_surface_state(device, image, aspect,
|
||||
&isl_view,
|
||||
is_storage ?
|
||||
ISL_SURF_USAGE_STORAGE_BIT :
|
||||
ISL_SURF_USAGE_TEXTURE_BIT,
|
||||
aux_usage, NULL,
|
||||
read_only_layout ?
|
||||
ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL : 0,
|
||||
&state);
|
||||
|
||||
memcpy(out->address + vplane * ANV_SURFACE_STATE_SIZE,
|
||||
state.state_data.data, ANV_SURFACE_STATE_SIZE);
|
||||
}
|
||||
} else {
|
||||
memcpy(out->address, device->host_null_surface_state,
|
||||
ANV_SURFACE_STATE_SIZE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: {
|
||||
const VkTexelBufferDescriptorInfoEXT *texel_info =
|
||||
res->data.pTexelBuffer;
|
||||
|
||||
if (!texel_info_is_null(texel_info)) {
|
||||
struct anv_format_plane format =
|
||||
anv_get_format_plane(device->physical,
|
||||
texel_info->format,
|
||||
0, VK_IMAGE_TILING_LINEAR);
|
||||
const uint32_t format_bs =
|
||||
isl_format_get_layout(format.isl_format)->bpb / 8;
|
||||
|
||||
anv_fill_buffer_surface_state(
|
||||
device, out->address,
|
||||
format.isl_format, format.swizzle,
|
||||
res->type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER ?
|
||||
ISL_SURF_USAGE_STORAGE_BIT : ISL_SURF_USAGE_TEXTURE_BIT,
|
||||
anv_address_from_u64(texel_info->addressRange.address),
|
||||
align_down_npot_u64(texel_info->addressRange.size, format_bs),
|
||||
format_bs);
|
||||
} else {
|
||||
memcpy(out->address, device->host_null_surface_state,
|
||||
ANV_SURFACE_STATE_SIZE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: {
|
||||
const VkDeviceAddressRangeEXT *addr_info = res->data.pAddressRange;
|
||||
|
||||
if (!address_range_is_null(addr_info)) {
|
||||
VkDeviceSize range = addr_info->size;
|
||||
|
||||
/* We report a bounds checking alignment of 32B for the sake of
|
||||
* block messages which read an entire register worth at a time.
|
||||
*/
|
||||
if (res->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
|
||||
range = align64(range, ANV_UBO_ALIGNMENT);
|
||||
|
||||
isl_surf_usage_flags_t usage =
|
||||
res->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ?
|
||||
ISL_SURF_USAGE_CONSTANT_BUFFER_BIT :
|
||||
ISL_SURF_USAGE_STORAGE_BIT;
|
||||
|
||||
enum isl_format format =
|
||||
anv_isl_format_for_descriptor_type(device, res->type);
|
||||
|
||||
isl_buffer_fill_state(&device->isl_dev, out->address,
|
||||
.address = addr_info->address,
|
||||
.mocs = isl_mocs(&device->isl_dev, usage, false),
|
||||
.size_B = range,
|
||||
.format = format,
|
||||
.swizzle = ISL_SWIZZLE_IDENTITY,
|
||||
.stride_B = 1,
|
||||
.usage = usage);
|
||||
} else {
|
||||
memcpy(out->address, device->host_null_surface_state,
|
||||
ANV_SURFACE_STATE_SIZE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
|
||||
const VkDeviceAddressRangeEXT *addr_info = res->data.pAddressRange;
|
||||
uint64_t desc_data = addr_info ? addr_info->address : 0;
|
||||
|
||||
memcpy(out->address, &desc_data, sizeof(desc_data));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
UNREACHABLE("Invalid descriptor type");
|
||||
}
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1738,6 +1738,20 @@ anv_image_init_sparse_bindings(struct anv_image *image,
|
|||
explicit_addresses = opaque_info->opaqueCaptureDescriptorData;
|
||||
}
|
||||
|
||||
if (image->vk.create_flags & VK_IMAGE_CREATE_DESCRIPTOR_HEAP_CAPTURE_REPLAY_BIT_EXT) {
|
||||
alloc_flags |= ANV_BO_ALLOC_FIXED_ADDRESS;
|
||||
|
||||
const VkOpaqueCaptureDataCreateInfoEXT *opaque_info =
|
||||
vk_find_struct_const(create_info->vk_info->pNext,
|
||||
OPAQUE_CAPTURE_DATA_CREATE_INFO_EXT);
|
||||
if (opaque_info) {
|
||||
assert(opaque_info->pData[0].size ==
|
||||
sizeof(struct anv_image_opaque_capture_data));
|
||||
explicit_addresses =
|
||||
(const struct anv_image_opaque_capture_data *)opaque_info->pData;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t total_size = 0;
|
||||
for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; i++) {
|
||||
struct anv_image_binding *b = &image->bindings[i];
|
||||
|
|
@ -4294,3 +4308,30 @@ anv_layout_has_untracked_aux_writes(const struct intel_device_info * const devin
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
VkResult anv_GetImageOpaqueCaptureDataEXT(
|
||||
VkDevice _device,
|
||||
uint32_t imageCount,
|
||||
const VkImage* pImages,
|
||||
VkHostAddressRangeEXT* pDatas)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_device, device, _device);
|
||||
|
||||
for (uint32_t i = 0; i < imageCount; i++) {
|
||||
ANV_FROM_HANDLE(anv_image, image, pImages[i]);
|
||||
|
||||
if (pDatas[i].size < sizeof(uint64_t))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
if (anv_image_is_sparse(image) &&
|
||||
(image->vk.create_flags & VK_IMAGE_CREATE_DESCRIPTOR_HEAP_CAPTURE_REPLAY_BIT_EXT)) {
|
||||
*((uint64_t *)pDatas[i].address) = anv_address_physical(
|
||||
image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address);
|
||||
} else {
|
||||
*((uint64_t *)pDatas[i].address) = 0;
|
||||
}
|
||||
pDatas[i].size = sizeof(uint64_t);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3420,3 +3420,34 @@ VkResult anv_GetPhysicalDeviceCooperativeMatrixFlexibleDimensionsPropertiesNV(
|
|||
/* TODO: When we enable flexible dimensions, fill this properly. */
|
||||
return vk_outarray_status(&out);
|
||||
}
|
||||
|
||||
VkDeviceSize anv_GetPhysicalDeviceDescriptorSizeEXT(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
VkDescriptorType descriptorType)
|
||||
{
|
||||
switch (descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
return ANV_SAMPLER_STATE_SIZE;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
return ANV_SURFACE_STATE_SIZE +
|
||||
align(ANV_SAMPLER_STATE_SIZE, ANV_SURFACE_STATE_SIZE);
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
||||
return ANV_SURFACE_STATE_SIZE;
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
|
||||
return sizeof(uint64_t);
|
||||
|
||||
default:
|
||||
UNREACHABLE("invalid descriptor type");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -945,6 +945,8 @@ uint32_t anv_state_reserved_array_pool_state_index(struct anv_state_reserved_arr
|
|||
struct anv_state state);
|
||||
void anv_state_reserved_array_pool_free(struct anv_state_reserved_array_pool *pool,
|
||||
struct anv_state state);
|
||||
void anv_state_reserved_array_pool_index_free(struct anv_state_reserved_array_pool *pool,
|
||||
uint32_t index);
|
||||
|
||||
VkResult anv_state_table_init(struct anv_state_table *table,
|
||||
struct anv_device *device,
|
||||
|
|
|
|||
|
|
@ -159,3 +159,58 @@ void anv_DestroySampler(
|
|||
|
||||
vk_sampler_destroy(&device->vk, pAllocator, &sampler->vk);
|
||||
}
|
||||
|
||||
VkResult anv_RegisterCustomBorderColorEXT(
|
||||
VkDevice _device,
|
||||
const VkSamplerCustomBorderColorCreateInfoEXT* pBorderColor,
|
||||
VkBool32 requestIndex,
|
||||
uint32_t* pIndex)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_device, device, _device);
|
||||
|
||||
struct anv_state color_state = requestIndex ?
|
||||
anv_state_reserved_array_pool_alloc_index(
|
||||
&device->custom_border_colors, *pIndex) :
|
||||
anv_state_reserved_array_pool_alloc(
|
||||
&device->custom_border_colors, true);
|
||||
|
||||
if (color_state.alloc_size == 0)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
|
||||
*pIndex = anv_state_reserved_array_pool_state_index(
|
||||
&device->custom_border_colors, color_state);
|
||||
|
||||
union isl_color_value color = { .u32 = {
|
||||
pBorderColor->customBorderColor.uint32[0],
|
||||
pBorderColor->customBorderColor.uint32[1],
|
||||
pBorderColor->customBorderColor.uint32[2],
|
||||
pBorderColor->customBorderColor.uint32[3],
|
||||
}
|
||||
};
|
||||
|
||||
const struct anv_format *format_desc =
|
||||
pBorderColor->format != VK_FORMAT_UNDEFINED ?
|
||||
anv_get_format(device->physical, pBorderColor->format) : NULL;
|
||||
|
||||
if (format_desc && format_desc->n_planes == 1 &&
|
||||
!isl_swizzle_is_identity(format_desc->planes[0].swizzle)) {
|
||||
const struct anv_format_plane *fmt_plane = &format_desc->planes[0];
|
||||
|
||||
assert(!isl_format_has_int_channel(fmt_plane->isl_format));
|
||||
color = isl_color_value_swizzle(color, fmt_plane->swizzle, true);
|
||||
}
|
||||
|
||||
memcpy(color_state.map, color.u32, sizeof(color));
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void anv_UnregisterCustomBorderColorEXT(
|
||||
VkDevice _device,
|
||||
uint32_t index)
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_device, device, _device);
|
||||
|
||||
anv_state_reserved_array_pool_index_free(
|
||||
&device->custom_border_colors, index);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue