Mesa (master): radv: Add ycbcr samplers in descriptor set layouts.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Apr 25 20:08:16 UTC 2019


Module: Mesa
Branch: master
Commit: 7f6732ac69ccea2826e57503dced49a139339376
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7f6732ac69ccea2826e57503dced49a139339376

Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date:   Thu Mar 21 01:29:33 2019 +0100

radv: Add ycbcr samplers in descriptor set layouts.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>

---

 src/amd/vulkan/radv_descriptor_set.c | 57 ++++++++++++++++++++++++++++++++++--
 src/amd/vulkan/radv_descriptor_set.h | 22 ++++++++++++++
 2 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/src/amd/vulkan/radv_descriptor_set.c b/src/amd/vulkan/radv_descriptor_set.c
index b048f1f7cf9..7d5b05ad464 100644
--- a/src/amd/vulkan/radv_descriptor_set.c
+++ b/src/amd/vulkan/radv_descriptor_set.c
@@ -30,6 +30,7 @@
 #include "util/mesa-sha1.h"
 #include "radv_private.h"
 #include "sid.h"
+#include "vk_format.h"
 #include "vk_util.h"
 
 
@@ -82,17 +83,31 @@ VkResult radv_CreateDescriptorSetLayout(
 
 	uint32_t max_binding = 0;
 	uint32_t immutable_sampler_count = 0;
+	uint32_t ycbcr_sampler_count = 0;
 	for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) {
 		max_binding = MAX2(max_binding, pCreateInfo->pBindings[j].binding);
 		if ((pCreateInfo->pBindings[j].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
 		     pCreateInfo->pBindings[j].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) &&
-		     pCreateInfo->pBindings[j].pImmutableSamplers)
+		     pCreateInfo->pBindings[j].pImmutableSamplers) {
 			immutable_sampler_count += pCreateInfo->pBindings[j].descriptorCount;
+
+			bool has_ycbcr_sampler = false;
+			for (unsigned i = 0; i < pCreateInfo->pBindings[j].descriptorCount; ++i) {
+				if (radv_sampler_from_handle(pCreateInfo->pBindings[j].pImmutableSamplers[i])->ycbcr_sampler)
+					has_ycbcr_sampler = true;
+			}
+
+			if (has_ycbcr_sampler)
+				ycbcr_sampler_count += pCreateInfo->pBindings[j].descriptorCount;
+		}
 	}
 
 	uint32_t samplers_offset = sizeof(struct radv_descriptor_set_layout) +
 		(max_binding + 1) * sizeof(set_layout->binding[0]);
 	size_t size = samplers_offset + immutable_sampler_count * 4 * sizeof(uint32_t);
+	if (ycbcr_sampler_count > 0) {
+		size += ycbcr_sampler_count * sizeof(struct radv_sampler_ycbcr_conversion) + (max_binding + 1) * sizeof(uint32_t);
+	}
 
 	set_layout = vk_alloc2(&device->alloc, pAllocator, size, 8,
 				 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
@@ -103,6 +118,15 @@ VkResult radv_CreateDescriptorSetLayout(
 
 	/* We just allocate all the samplers at the end of the struct */
 	uint32_t *samplers = (uint32_t*)&set_layout->binding[max_binding + 1];
+	struct radv_sampler_ycbcr_conversion *ycbcr_samplers = NULL;
+	uint32_t *ycbcr_sampler_offsets = NULL;
+
+	if (ycbcr_sampler_count > 0) {
+		ycbcr_sampler_offsets = samplers + 4 * immutable_sampler_count;
+		set_layout->ycbcr_sampler_offsets_offset = (char*)ycbcr_sampler_offsets - (char*)set_layout;
+		ycbcr_samplers = (struct radv_sampler_ycbcr_conversion *)(ycbcr_sampler_offsets + max_binding + 1);
+	} else
+		set_layout->ycbcr_sampler_offsets_offset = 0;
 
 	VkDescriptorSetLayoutBinding *bindings = create_sorted_bindings(pCreateInfo->pBindings,
 	                                                                pCreateInfo->bindingCount);
@@ -128,6 +152,24 @@ VkResult radv_CreateDescriptorSetLayout(
 		uint32_t alignment;
 		unsigned binding_buffer_count = 0;
 		uint32_t descriptor_count = binding->descriptorCount;
+		bool has_ycbcr_sampler = false;
+
+		/* main image + fmask */
+		uint32_t max_sampled_image_descriptors = 2;
+
+		if (binding->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
+		    binding->pImmutableSamplers) {
+			for (unsigned i = 0; i < binding->descriptorCount; ++i) {
+				struct radv_sampler_ycbcr_conversion *conversion =
+					radv_sampler_from_handle(binding->pImmutableSamplers[i])->ycbcr_sampler;
+
+				if (conversion) {
+					has_ycbcr_sampler = true;
+					max_sampled_image_descriptors = MAX2(max_sampled_image_descriptors,
+					                                     vk_format_get_plane_count(conversion->format));
+				}
+			}
+		}
 
 		switch (binding->descriptorType) {
 		case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
@@ -157,7 +199,7 @@ VkResult radv_CreateDescriptorSetLayout(
 			break;
 		case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
 			/* main descriptor + fmask descriptor + sampler */
-			set_layout->binding[b].size = 96;
+			set_layout->binding[b].size = 32 + 32 * max_sampled_image_descriptors;
 			binding_buffer_count = 1;
 			alignment = 32;
 			break;
@@ -211,6 +253,17 @@ VkResult radv_CreateDescriptorSetLayout(
 			}
 			samplers += 4 * binding->descriptorCount;
 			samplers_offset += 4 * sizeof(uint32_t) * binding->descriptorCount;
+
+			if (has_ycbcr_sampler) {
+				ycbcr_sampler_offsets[b] = (const char*)ycbcr_samplers - (const char*)set_layout;
+				for (uint32_t i = 0; i < binding->descriptorCount; i++) {
+					if (radv_sampler_from_handle(binding->pImmutableSamplers[i])->ycbcr_sampler)
+						ycbcr_samplers[i] = *radv_sampler_from_handle(binding->pImmutableSamplers[i])->ycbcr_sampler;
+					else
+						ycbcr_samplers[i].format = VK_FORMAT_UNDEFINED;
+				}
+				ycbcr_samplers += binding->descriptorCount;
+			}
 		}
 
 		set_layout->size += descriptor_count * set_layout->binding[b].size;
diff --git a/src/amd/vulkan/radv_descriptor_set.h b/src/amd/vulkan/radv_descriptor_set.h
index 7b13c6fb621..55cc1c9c462 100644
--- a/src/amd/vulkan/radv_descriptor_set.h
+++ b/src/amd/vulkan/radv_descriptor_set.h
@@ -71,6 +71,8 @@ struct radv_descriptor_set_layout {
    bool has_immutable_samplers;
    bool has_variable_descriptors;
 
+   uint32_t ycbcr_sampler_offsets_offset;
+
    /* Bindings in this descriptor set */
    struct radv_descriptor_set_binding_layout binding[0];
 };
@@ -95,4 +97,24 @@ radv_immutable_samplers(const struct radv_descriptor_set_layout *set,
                         const struct radv_descriptor_set_binding_layout *binding) {
 	return (const uint32_t*)((const char*)set + binding->immutable_samplers_offset);
 }
+
+static inline unsigned
+radv_combined_image_descriptor_sampler_offset(const struct radv_descriptor_set_binding_layout *binding)
+{
+	return binding->size - ((!binding->immutable_samplers_equal) ? 32 : 0);
+}
+
+static inline const struct radv_sampler_ycbcr_conversion *
+radv_immutable_ycbcr_samplers(const struct radv_descriptor_set_layout *set,
+                              unsigned binding_index)
+{
+	if (!set->ycbcr_sampler_offsets_offset)
+		return NULL;
+
+	const uint32_t *offsets = (const uint32_t*)((const char*)set + set->ycbcr_sampler_offsets_offset);
+
+	if (offsets[binding_index] == 0)
+		return NULL;
+	return (const struct radv_sampler_ycbcr_conversion *)((const char*)set + offsets[binding_index]);
+}
 #endif /* RADV_DESCRIPTOR_SET_H */




More information about the mesa-commit mailing list