aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <[email protected]>2019-03-21 01:29:33 +0100
committerBas Nieuwenhuizen <[email protected]>2019-04-25 19:56:20 +0000
commit7f6732ac69ccea2826e57503dced49a139339376 (patch)
treec4e6e4689e7bceee6bc6b2918f0169706030b3e4
parent427024bf2e9a0464fae1481d81c59579fcc506cf (diff)
radv: Add ycbcr samplers in descriptor set layouts.
Reviewed-by: Samuel Pitoiset <[email protected]>
-rw-r--r--src/amd/vulkan/radv_descriptor_set.c57
-rw-r--r--src/amd/vulkan/radv_descriptor_set.h22
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 */