diff --git a/src/nouveau/vulkan/nvk_buffer_view.c b/src/nouveau/vulkan/nvk_buffer_view.c index 178d605475e..aab3d2af179 100644 --- a/src/nouveau/vulkan/nvk_buffer_view.c +++ b/src/nouveau/vulkan/nvk_buffer_view.c @@ -67,22 +67,33 @@ nvk_CreateBufferView(VkDevice _device, nvk_edb_bview_cache_get_descriptor(dev, &dev->edb_bview_cache, addr, view->vk.range, format); } else { - uint32_t desc[8]; - nil_buffer_fill_tic(&pdev->info, addr, nil_format(format), - view->vk.elements, &desc); + if (pdev->info.cls_eng3d >= MAXWELL_A || + (buffer->vk.usage & VK_BUFFER_USAGE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR)) { + uint32_t desc[8]; + nil_buffer_fill_tic(&pdev->info, addr, nil_format(format), + view->vk.elements, &desc); - uint32_t desc_index; - result = nvk_descriptor_table_add(dev, &dev->images, - desc, sizeof(desc), - &desc_index); - if (result != VK_SUCCESS) { - vk_buffer_view_destroy(&dev->vk, pAllocator, &view->vk); - return result; + uint32_t desc_index; + result = nvk_descriptor_table_add(dev, &dev->images, + desc, sizeof(desc), + &desc_index); + if (result != VK_SUCCESS) { + vk_buffer_view_destroy(&dev->vk, pAllocator, &view->vk); + return result; + } + + view->desc = (struct nvk_buffer_view_descriptor) { + .image_index = desc_index, + }; + } + if (pdev->info.cls_eng3d < MAXWELL_A && + (buffer->vk.usage & VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT_KHR)) { + // Kepler + view->su_info = nil_buffer_fill_su_info(&pdev->info, + addr, + nil_format(format), + view->vk.elements); } - - view->desc = (struct nvk_buffer_view_descriptor) { - .image_index = desc_index, - }; } *pBufferView = nvk_buffer_view_to_handle(view); diff --git a/src/nouveau/vulkan/nvk_buffer_view.h b/src/nouveau/vulkan/nvk_buffer_view.h index 733aee1d358..1903eb0838c 100644 --- a/src/nouveau/vulkan/nvk_buffer_view.h +++ b/src/nouveau/vulkan/nvk_buffer_view.h @@ -21,7 +21,12 @@ struct nvk_buffer_view { struct vk_buffer_view vk; struct nvk_buffer_view_descriptor desc; + + /* Used for uniform texel buffers on Kepler and everything on Maxwell+ */ struct nvk_edb_buffer_view_descriptor edb_desc; + + /* Used for storage texel buffers on Kepler */ + struct nil_su_info su_info; }; VK_DEFINE_NONDISP_HANDLE_CASTS(nvk_buffer_view, vk.base, VkBufferView, diff --git a/src/nouveau/vulkan/nvk_descriptor_set.c b/src/nouveau/vulkan/nvk_descriptor_set.c index 4fcb9f7d7e3..6217e331e2d 100644 --- a/src/nouveau/vulkan/nvk_descriptor_set.c +++ b/src/nouveau/vulkan/nvk_descriptor_set.c @@ -17,6 +17,8 @@ #include "util/format/u_format.h" +#include "clb097.h" + static inline uint32_t align_u32(uint32_t v, uint32_t a) { @@ -117,53 +119,73 @@ write_sampled_image_view_desc(struct nvk_descriptor_set *set, } static void -get_storage_image_view_desc(const VkDescriptorImageInfo *const info, +get_storage_image_view_desc(const struct nvk_physical_device *pdev, + const VkDescriptorImageInfo *const info, void *dst, size_t dst_size) { - struct nvk_storage_image_descriptor desc = { }; + if (pdev->info.cls_eng3d >= MAXWELL_A) { + struct nvk_storage_image_descriptor desc = { }; - if (info && info->imageView != VK_NULL_HANDLE) { - VK_FROM_HANDLE(nvk_image_view, view, info->imageView); + if (info && info->imageView != VK_NULL_HANDLE) { + VK_FROM_HANDLE(nvk_image_view, view, info->imageView); - /* Storage images are always single plane */ - assert(view->plane_count == 1); - uint8_t plane = 0; + /* Storage images are always single plane */ + assert(view->plane_count == 1); + uint8_t plane = 0; - assert(view->planes[plane].storage_desc_index > 0); - assert(view->planes[plane].storage_desc_index < (1 << 20)); + assert(view->planes[plane].storage_desc_index > 0); + assert(view->planes[plane].storage_desc_index < (1 << 20)); - desc.image_index = view->planes[plane].storage_desc_index; + desc.image_index = view->planes[plane].storage_desc_index; - const struct nil_Extent4D_Samples px_extent_sa = - nil_px_extent_sa(view->planes[plane].sample_layout); - desc.sw_log2 = util_logbase2(px_extent_sa.width); - desc.sh_log2 = util_logbase2(px_extent_sa.height); + const struct nil_Extent4D_Samples px_extent_sa = + nil_px_extent_sa(view->planes[plane].sample_layout); + desc.sw_log2 = util_logbase2(px_extent_sa.width); + desc.sh_log2 = util_logbase2(px_extent_sa.height); - const enum nil_sample_layout slayout = view->planes[plane].sample_layout; - if (slayout != NIL_SAMPLE_LAYOUT_1X1) { - uint32_t samples = nil_sample_layout_samples(slayout); - assert(samples <= 16); - for (uint32_t s = 0; s < samples; s++) { - const struct nil_sample_offset off = nil_sample_offset(slayout, s); - assert(off.x < 4 && off.y < 4); - uint32_t s_xy = off.y << 2 | off.x; - desc.sample_map |= s_xy << (s * 4); + const enum nil_sample_layout slayout = view->planes[plane].sample_layout; + if (slayout != NIL_SAMPLE_LAYOUT_1X1) { + uint32_t samples = nil_sample_layout_samples(slayout); + assert(samples <= 16); + for (uint32_t s = 0; s < samples; s++) { + const struct nil_sample_offset off = nil_sample_offset(slayout, s); + assert(off.x < 4 && off.y < 4); + uint32_t s_xy = off.y << 2 | off.x; + desc.sample_map |= s_xy << (s * 4); + } } } - } - assert(sizeof(desc) <= dst_size); - memcpy(dst, &desc, sizeof(desc)); + assert(sizeof(desc) <= dst_size); + memcpy(dst, &desc, sizeof(desc)); + } else { + struct nvk_kepler_storage_image_descriptor desc = { }; + + if (info && info->imageView != VK_NULL_HANDLE) { + VK_FROM_HANDLE(nvk_image_view, view, info->imageView); + + /* Storage images are always single plane */ + assert(view->plane_count == 1); + + desc.su_info = view->su_info; + } else { + desc.su_info = nil_fill_null_su_info(&pdev->info); + } + + assert(sizeof(desc) <= dst_size); + memcpy(dst, &desc, sizeof(desc)); + } } static void -write_storage_image_view_desc(struct nvk_descriptor_set *set, +write_storage_image_view_desc(const struct nvk_physical_device *pdev, + struct nvk_descriptor_set *set, const VkDescriptorImageInfo *const info, uint32_t binding, uint32_t elem) { uint32_t dst_size; void *dst = desc_ubo_data(set, binding, elem, &dst_size); - get_storage_image_view_desc(info, dst, dst_size); + get_storage_image_view_desc(pdev, info, dst, dst_size); } static union nvk_buffer_descriptor @@ -284,7 +306,8 @@ static void write_buffer_view_desc(const struct nvk_physical_device *pdev, struct nvk_descriptor_set *set, const VkBufferView bufferView, - uint32_t binding, uint32_t elem) + uint32_t binding, uint32_t elem, + VkDescriptorType descType) { VK_FROM_HANDLE(nvk_buffer_view, view, bufferView); @@ -293,11 +316,22 @@ write_buffer_view_desc(const struct nvk_physical_device *pdev, if (view != NULL) desc = view->edb_desc; write_desc(set, binding, elem, &desc, sizeof(desc)); - } else { + } else if (pdev->info.cls_eng3d >= MAXWELL_A || + descType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) { struct nvk_buffer_view_descriptor desc = { }; if (view != NULL) desc = view->desc; write_desc(set, binding, elem, &desc, sizeof(desc)); + } else {// Kepler + struct nvk_kepler_storage_buffer_view_descriptor desc = { }; + assert(descType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER); + + if (view != NULL) + desc.su_info = view->su_info; + else + desc.su_info = nil_fill_null_su_info(&pdev->info); + + write_desc(set, binding, elem, &desc, sizeof(desc)); } } @@ -339,7 +373,7 @@ nvk_UpdateDescriptorSets(VkDevice device, case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: for (uint32_t j = 0; j < write->descriptorCount; j++) { - write_storage_image_view_desc(set, write->pImageInfo + j, + write_storage_image_view_desc(pdev, set, write->pImageInfo + j, write->dstBinding, write->dstArrayElement + j); } @@ -349,7 +383,8 @@ nvk_UpdateDescriptorSets(VkDevice device, case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: for (uint32_t j = 0; j < write->descriptorCount; j++) { write_buffer_view_desc(pdev, set, write->pTexelBufferView[j], - write->dstBinding, write->dstArrayElement + j); + write->dstBinding, write->dstArrayElement + j, + write->descriptorType); } break; @@ -473,7 +508,7 @@ nvk_push_descriptor_set_update(struct nvk_device *dev, case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: for (uint32_t j = 0; j < write->descriptorCount; j++) { - write_storage_image_view_desc(&set, write->pImageInfo + j, + write_storage_image_view_desc(pdev, &set, write->pImageInfo + j, write->dstBinding, write->dstArrayElement + j); } @@ -483,7 +518,8 @@ nvk_push_descriptor_set_update(struct nvk_device *dev, case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: for (uint32_t j = 0; j < write->descriptorCount; j++) { write_buffer_view_desc(pdev, &set, write->pTexelBufferView[j], - write->dstBinding, write->dstArrayElement + j); + write->dstBinding, write->dstArrayElement + j, + write->descriptorType); } break; @@ -888,7 +924,7 @@ nvk_descriptor_set_write_template(struct nvk_device *dev, const VkDescriptorImageInfo *info = data + entry->offset + j * entry->stride; - write_storage_image_view_desc(set, info, + write_storage_image_view_desc(pdev, set, info, entry->binding, entry->array_element + j); } @@ -902,7 +938,8 @@ nvk_descriptor_set_write_template(struct nvk_device *dev, write_buffer_view_desc(pdev, set, *bview, entry->binding, - entry->array_element + j); + entry->array_element + j, + entry->type); } break; @@ -1025,7 +1062,7 @@ nvk_GetDescriptorEXT(VkDevice _device, break; case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - get_storage_image_view_desc(pDescriptorInfo->data.pStorageImage, + get_storage_image_view_desc(pdev, pDescriptorInfo->data.pStorageImage, pDescriptor, dataSize); break; diff --git a/src/nouveau/vulkan/nvk_descriptor_set_layout.c b/src/nouveau/vulkan/nvk_descriptor_set_layout.c index dd777bd3a33..1a85e1e5273 100644 --- a/src/nouveau/vulkan/nvk_descriptor_set_layout.c +++ b/src/nouveau/vulkan/nvk_descriptor_set_layout.c @@ -13,6 +13,8 @@ #include "vk_pipeline_layout.h" +#include "clb097.h" + static bool binding_has_immutable_samplers(const VkDescriptorSetLayoutBinding *binding) { @@ -26,6 +28,27 @@ binding_has_immutable_samplers(const VkDescriptorSetLayoutBinding *binding) } } +static uint32_t +nvk_max_descriptor_size(const struct nv_device_info *info) +{ + // This should be constant-folded. + uint32_t max_desc_size = 0; + + max_desc_size = MAX2(max_desc_size, sizeof(struct nvk_sampled_image_descriptor)); + max_desc_size = MAX2(max_desc_size, sizeof(struct nvk_edb_buffer_view_descriptor)); + max_desc_size = MAX2(max_desc_size, sizeof(union nvk_buffer_descriptor)); + + if (info->cls_eng3d >= MAXWELL_A) { + max_desc_size = MAX2(max_desc_size, sizeof(struct nvk_storage_image_descriptor)); + max_desc_size = MAX2(max_desc_size, sizeof(struct nvk_buffer_view_descriptor)); + } else { + max_desc_size = MAX2(max_desc_size, sizeof(struct nvk_kepler_storage_image_descriptor)); + max_desc_size = MAX2(max_desc_size, sizeof(struct nvk_kepler_storage_buffer_view_descriptor)); + } + + return max_desc_size; +} + void nvk_descriptor_stride_align_for_type(const struct nvk_physical_device *pdev, VkPipelineLayoutCreateFlags layout_flags, @@ -43,7 +66,12 @@ nvk_descriptor_stride_align_for_type(const struct nvk_physical_device *pdev, break; case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - *stride = *alignment = sizeof(struct nvk_storage_image_descriptor); + if (pdev->info.cls_eng3d >= MAXWELL_A) { + *stride = *alignment = sizeof(struct nvk_storage_image_descriptor); + } else { + *stride = sizeof(struct nvk_kepler_storage_image_descriptor); + *alignment = 16; + } break; case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: @@ -51,8 +79,12 @@ nvk_descriptor_stride_align_for_type(const struct nvk_physical_device *pdev, if ((layout_flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT) || nvk_use_edb_buffer_views(pdev)) { *stride = *alignment = sizeof(struct nvk_edb_buffer_view_descriptor); - } else { + } else if (pdev->info.cls_eng3d >= MAXWELL_A || + type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) { *stride = *alignment = sizeof(struct nvk_buffer_view_descriptor); + } else { + *stride = sizeof(struct nvk_kepler_storage_buffer_view_descriptor); + *alignment = 16; } break; @@ -74,7 +106,7 @@ nvk_descriptor_stride_align_for_type(const struct nvk_physical_device *pdev, case VK_DESCRIPTOR_TYPE_MUTABLE_EXT: *stride = *alignment = 0; if (type_list == NULL) - *stride = *alignment = NVK_MAX_DESCRIPTOR_SIZE; + *stride = *alignment = nvk_max_descriptor_size(&pdev->info); for (unsigned i = 0; type_list && i < type_list->descriptorTypeCount; i++) { /* This shouldn't recurse */ assert(type_list->pDescriptorTypes[i] != @@ -470,7 +502,7 @@ nvk_GetDescriptorSetLayoutSupport(VkDevice device, uint32_t max_buffer_size; if (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR) - max_buffer_size = NVK_PUSH_DESCRIPTOR_SET_SIZE; + max_buffer_size = NVK_MAX_PUSH_DESCRIPTORS * nvk_max_descriptor_size(&pdev->info); else max_buffer_size = NVK_MAX_DESCRIPTOR_SET_SIZE; diff --git a/src/nouveau/vulkan/nvk_descriptor_types.h b/src/nouveau/vulkan/nvk_descriptor_types.h index 2cb8cc39b64..8890e47a0dd 100644 --- a/src/nouveau/vulkan/nvk_descriptor_types.h +++ b/src/nouveau/vulkan/nvk_descriptor_types.h @@ -9,6 +9,8 @@ #include "nvk_physical_device.h" +#include "nil.h" + #define NVK_IMAGE_DESCRIPTOR_IMAGE_INDEX_MASK 0x000fffff #define NVK_IMAGE_DESCRIPTOR_SAMPLER_INDEX_MASK 0xfff00000 @@ -40,6 +42,14 @@ PRAGMA_DIAGNOSTIC_POP static_assert(sizeof(struct nvk_storage_image_descriptor) == 8, "nvk_storage_image_descriptor has no holes"); +struct nvk_kepler_storage_image_descriptor { + struct nil_su_info su_info; +}; + +struct nvk_kepler_storage_buffer_view_descriptor { + struct nil_su_info su_info; +}; + PRAGMA_DIAGNOSTIC_PUSH PRAGMA_DIAGNOSTIC_ERROR(-Wpadded) struct nvk_buffer_view_descriptor { diff --git a/src/nouveau/vulkan/nvk_image_view.c b/src/nouveau/vulkan/nvk_image_view.c index bb048d52131..16312cfb3ab 100644 --- a/src/nouveau/vulkan/nvk_image_view.c +++ b/src/nouveau/vulkan/nvk_image_view.c @@ -12,6 +12,8 @@ #include "vk_format.h" +#include "clb097.h" + static enum nil_view_type vk_image_view_type_to_nil_view_type(VkImageViewType view_type) { @@ -230,29 +232,38 @@ nvk_image_view_init(struct nvk_device *dev, } } - if (image->vk.samples != VK_SAMPLE_COUNT_1_BIT) - nil_image = nil_msaa_image_as_sa(&nil_image); + if (pdev->info.cls_eng3d >= MAXWELL_A) { + if (image->vk.samples != VK_SAMPLE_COUNT_1_BIT) + nil_image = nil_msaa_image_as_sa(&nil_image); - uint32_t tic[8]; - nil_image_fill_tic(&nil_image, &pdev->info, &nil_view, - base_addr, &tic); + uint32_t tic[8]; + nil_image_fill_tic(&nil_image, &pdev->info, &nil_view, + base_addr, &tic); - uint32_t desc_index = 0; - if (cap_info != NULL) { - assert(view->plane_count == 1); - desc_index = cap.single_plane.storage_desc_index; - result = nvk_descriptor_table_insert(dev, &dev->images, - desc_index, tic, sizeof(tic)); + uint32_t desc_index = 0; + if (cap_info != NULL) { + assert(view->plane_count == 1); + desc_index = cap.single_plane.storage_desc_index; + result = nvk_descriptor_table_insert(dev, &dev->images, + desc_index, tic, + sizeof(tic)); + } else { + result = nvk_descriptor_table_add(dev, &dev->images, + tic, sizeof(tic), + &desc_index); + } + if (result != VK_SUCCESS) { + nvk_image_view_finish(dev, view); + return result; + } + + view->planes[view_plane].storage_desc_index = desc_index; } else { - result = nvk_descriptor_table_add(dev, &dev->images, - tic, sizeof(tic), &desc_index); + assert(view_plane == 0); + view->su_info = nil_fill_su_info(&pdev->info, + &nil_image, &nil_view, + base_addr); } - if (result != VK_SUCCESS) { - nvk_image_view_finish(dev, view); - return result; - } - - view->planes[view_plane].storage_desc_index = desc_index; } } diff --git a/src/nouveau/vulkan/nvk_image_view.h b/src/nouveau/vulkan/nvk_image_view.h index e534cd03b22..91f5015183e 100644 --- a/src/nouveau/vulkan/nvk_image_view.h +++ b/src/nouveau/vulkan/nvk_image_view.h @@ -28,6 +28,9 @@ struct nvk_image_view { /** Index in the image descriptor table for the storage image descriptor */ uint32_t storage_desc_index; } planes[NVK_MAX_IMAGE_PLANES]; + + /* Surface info for Kepler storage images */ + struct nil_su_info su_info; }; VK_DEFINE_NONDISP_HANDLE_CASTS(nvk_image_view, vk.base, VkImageView, diff --git a/src/nouveau/vulkan/nvk_private.h b/src/nouveau/vulkan/nvk_private.h index 5e2eb901baa..18a08f6e039 100644 --- a/src/nouveau/vulkan/nvk_private.h +++ b/src/nouveau/vulkan/nvk_private.h @@ -19,7 +19,9 @@ #define NVK_MIN_TEXEL_BUFFER_ALIGNMENT 16 #define NVK_MIN_UBO_ALIGNMENT 64 #define NVK_MAX_VIEWPORTS 16 -#define NVK_MAX_DESCRIPTOR_SIZE 16 +// This constant tracks the biggest descriptor size, it must be conservative +// From Maxwell we only use much smaller descriptors. +#define NVK_MAX_DESCRIPTOR_SIZE 32 #define NVK_MAX_PUSH_DESCRIPTORS 32 #define NVK_MAX_DESCRIPTOR_SET_SIZE (1u << 30) #define NVK_MAX_DESCRIPTORS (1 << 20)