type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC))
data |= ANV_DESCRIPTOR_ADDRESS_RANGE;
+ /* On Ivy Bridge and Bay Trail, we need swizzles textures in the shader
+ * Do not handle VK_DESCRIPTOR_TYPE_STORAGE_IMAGE and
+ * VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT because they already must
+ * have identity swizzle.
+ */
+ if (device->info.gen == 7 && !device->info.is_haswell &&
+ (type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
+ type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER))
+ data |= ANV_DESCRIPTOR_TEXTURE_SWIZZLE;
+
return data;
}
if (data & ANV_DESCRIPTOR_ADDRESS_RANGE)
size += sizeof(struct anv_address_range_descriptor);
+ if (data & ANV_DESCRIPTOR_TEXTURE_SWIZZLE)
+ size += sizeof(struct anv_texture_swizzle_descriptor);
+
return size;
}
+static bool
+anv_needs_descriptor_buffer(VkDescriptorType desc_type,
+ enum anv_descriptor_data desc_data)
+{
+ if (desc_type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT ||
+ anv_descriptor_data_size(desc_data) > 0)
+ return true;
+ return false;
+}
+
/** Returns the size in bytes of each descriptor with the given layout */
unsigned
anv_descriptor_size(const struct anv_descriptor_set_binding_layout *layout)
&device->instance->physicalDevice;
uint32_t surface_count[MESA_SHADER_STAGES] = { 0, };
+ bool needs_descriptor_buffer = false;
for (uint32_t b = 0; b < pCreateInfo->bindingCount; b++) {
const VkDescriptorSetLayoutBinding *binding = &pCreateInfo->pBindings[b];
enum anv_descriptor_data desc_data =
anv_descriptor_data_for_type(pdevice, binding->descriptorType);
+ if (anv_needs_descriptor_buffer(binding->descriptorType, desc_data))
+ needs_descriptor_buffer = true;
+
switch (binding->descriptorType) {
case VK_DESCRIPTOR_TYPE_SAMPLER:
/* There is no real limit on samplers */
break;
+ case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
+ /* Inline uniforms don't use a binding */
+ break;
+
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
if (anv_descriptor_data_supports_bindless(pdevice, desc_data, false))
break;
}
}
+ for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
+ if (needs_descriptor_buffer)
+ surface_count[s] += 1;
+ }
+
bool supported = true;
for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
/* Our maximum binding table size is 240 and we need to reserve 8 for
* of them to 32B.
*/
descriptor_bo_size += 32 * pCreateInfo->maxSets;
- descriptor_bo_size = ALIGN(descriptor_bo_size, 4096);
/* We align inline uniform blocks to 32B */
if (inline_info)
descriptor_bo_size += 32 * inline_info->maxInlineUniformBlockBindings;
+ descriptor_bo_size = ALIGN(descriptor_bo_size, 4096);
const size_t pool_size =
pCreateInfo->maxSets * sizeof(struct anv_descriptor_set) +
if (!pool)
return;
+ list_for_each_entry_safe(struct anv_descriptor_set, set,
+ &pool->desc_sets, pool_link) {
+ anv_descriptor_set_layout_unref(device, set->layout);
+ }
+
if (pool->bo.size) {
anv_gem_munmap(pool->bo.map, pool->bo.size);
anv_vma_free(device, &pool->bo);
anv_gem_close(device, pool->bo.gem_handle);
+ util_vma_heap_finish(&pool->bo_heap);
}
anv_state_stream_finish(&pool->surface_state_stream);
- list_for_each_entry_safe(struct anv_descriptor_set, set,
- &pool->desc_sets, pool_link) {
- anv_descriptor_set_destroy(device, pool, set);
- }
-
- util_vma_heap_finish(&pool->bo_heap);
-
vk_free2(&device->alloc, pAllocator, pool);
}
list_for_each_entry_safe(struct anv_descriptor_set, set,
&pool->desc_sets, pool_link) {
- anv_descriptor_set_destroy(device, pool, set);
+ anv_descriptor_set_layout_unref(device, set->layout);
}
+ list_inithead(&pool->desc_sets);
pool->next = 0;
pool->free_list = EMPTY;
/* Align the size to 32 so that alignment gaps don't cause extra holes
* in the heap which can lead to bad performance.
*/
+ uint32_t set_buffer_size = ALIGN(layout->descriptor_buffer_size, 32);
uint64_t pool_vma_offset =
- util_vma_heap_alloc(&pool->bo_heap,
- ALIGN(layout->descriptor_buffer_size, 32), 32);
+ util_vma_heap_alloc(&pool->bo_heap, set_buffer_size, 32);
if (pool_vma_offset == 0) {
anv_descriptor_pool_free_set(pool, set);
return vk_error(VK_ERROR_FRAGMENTED_POOL);
assert(pool_vma_offset >= POOL_HEAP_OFFSET &&
pool_vma_offset - POOL_HEAP_OFFSET <= INT32_MAX);
set->desc_mem.offset = pool_vma_offset - POOL_HEAP_OFFSET;
- set->desc_mem.alloc_size = layout->descriptor_buffer_size;
+ set->desc_mem.alloc_size = set_buffer_size;
set->desc_mem.map = pool->bo.map + set->desc_mem.offset;
set->desc_surface_state = anv_descriptor_pool_alloc_state(pool);
anv_descriptor_set_write_image_param(desc_map, image_param);
}
+
+ if (image_view && (bind_layout->data & ANV_DESCRIPTOR_TEXTURE_SWIZZLE)) {
+ assert(!(bind_layout->data & ANV_DESCRIPTOR_SAMPLED_IMAGE));
+ assert(image_view);
+ struct anv_texture_swizzle_descriptor desc_data[3];
+ memset(desc_data, 0, sizeof(desc_data));
+
+ for (unsigned p = 0; p < image_view->n_planes; p++) {
+ desc_data[p] = (struct anv_texture_swizzle_descriptor) {
+ .swizzle = {
+ (uint8_t)image_view->planes[p].isl.swizzle.r,
+ (uint8_t)image_view->planes[p].isl.swizzle.g,
+ (uint8_t)image_view->planes[p].isl.swizzle.b,
+ (uint8_t)image_view->planes[p].isl.swizzle.a,
+ },
+ };
+ }
+ memcpy(desc_map, desc_data,
+ MAX2(1, bind_layout->max_plane_count) * sizeof(desc_data[0]));
+ }
}
void