Signed-off-by: Lionel Landwerlin <lionel.g.landwer...@intel.com> --- src/intel/vulkan/anv_device.c | 69 +++++++++++++++++++++++++++++++++----- src/intel/vulkan/anv_extensions.py | 1 + src/intel/vulkan/anv_formats.c | 59 ++++++++++++++++++++++++++++++++ src/intel/vulkan/anv_image.c | 42 ++++++++++++++++------- src/intel/vulkan/anv_private.h | 4 +++ src/intel/vulkan/genX_state.c | 50 ++++++++++++++++++++++----- 6 files changed, 194 insertions(+), 31 deletions(-)
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index d576bb55315..1a5eee8a0b7 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -703,6 +703,13 @@ void anv_GetPhysicalDeviceFeatures2KHR( break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR: { + VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR *features = + (VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR *) ext; + features->samplerYcbcrConversion = true; + break; + } + default: anv_debug_ignored_stype(ext->sType); break; @@ -721,8 +728,12 @@ void anv_GetPhysicalDeviceProperties( const uint32_t max_raw_buffer_sz = devinfo->gen >= 7 ? (1ul << 30) : (1ul << 27); + /* These numbers have to account for multiplanar images where we rebuild + * things using shader snippets. + */ const uint32_t max_samplers = (devinfo->gen >= 8 || devinfo->is_haswell) ? - 128 : 16; + (128 / 3) : (16 / 3); + const uint32_t max_descriptors = 256 / 3; VkSampleCountFlags sample_counts = isl_device_get_sample_counts(&pdevice->isl_dev); @@ -749,14 +760,14 @@ void anv_GetPhysicalDeviceProperties( .maxPerStageDescriptorStorageImages = 64, .maxPerStageDescriptorInputAttachments = 64, .maxPerStageResources = 250, - .maxDescriptorSetSamplers = 256, - .maxDescriptorSetUniformBuffers = 256, + .maxDescriptorSetSamplers = max_descriptors, + .maxDescriptorSetUniformBuffers = max_descriptors, .maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2, - .maxDescriptorSetStorageBuffers = 256, + .maxDescriptorSetStorageBuffers = max_descriptors, .maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2, - .maxDescriptorSetSampledImages = 256, - .maxDescriptorSetStorageImages = 256, - .maxDescriptorSetInputAttachments = 256, + .maxDescriptorSetSampledImages = max_descriptors, + .maxDescriptorSetStorageImages = max_descriptors, + .maxDescriptorSetInputAttachments = max_descriptors, .maxVertexInputAttributes = MAX_VBS, .maxVertexInputBindings = MAX_VBS, .maxVertexInputAttributeOffset = 2047, @@ -1826,8 +1837,48 @@ void anv_GetImageMemoryRequirements2KHR( const VkImageMemoryRequirementsInfo2KHR* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements) { - anv_GetImageMemoryRequirements(_device, pInfo->image, - &pMemoryRequirements->memoryRequirements); + if (pInfo->pNext == NULL) { + anv_GetImageMemoryRequirements(_device, pInfo->image, + &pMemoryRequirements->memoryRequirements); + } else { + vk_foreach_struct_const(ext, pInfo->pNext) { + switch (ext->sType) { + case VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR: { + ANV_FROM_HANDLE(anv_image, image, pInfo->image); + ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_physical_device *pdevice = &device->instance->physicalDevice; + const VkImagePlaneMemoryRequirementsInfoKHR *plane_reqs = + (const VkImagePlaneMemoryRequirementsInfoKHR *) ext; + uint32_t plane = anv_image_aspect_to_plane(image->aspects, + plane_reqs->planeAspect); + + assert(image->planes[plane].offset == 0); + + /* The Vulkan spec (git aaed022) says: + * + * memoryTypeBits is a bitfield and contains one bit set for + * every supported memory type for the resource. The bit `1<<i` + * is set if and only if the memory type `i` in the + * VkPhysicalDeviceMemoryProperties structure for the physical + * device is supported. + * + * All types are currently supported for images. + */ + pMemoryRequirements->memoryRequirements.memoryTypeBits = + (1ull << pdevice->memory.type_count) - 1; + + pMemoryRequirements->memoryRequirements.size = image->planes[plane].size; + pMemoryRequirements->memoryRequirements.alignment = + image->planes[plane].alignment; + break; + } + + default: + anv_debug_ignored_stype(ext->sType); + break; + } + } + } vk_foreach_struct(ext, pMemoryRequirements->pNext) { switch (ext->sType) { diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py index 491e7086838..a828a668d65 100644 --- a/src/intel/vulkan/anv_extensions.py +++ b/src/intel/vulkan/anv_extensions.py @@ -74,6 +74,7 @@ EXTENSIONS = [ Extension('VK_KHR_push_descriptor', 1, True), Extension('VK_KHR_relaxed_block_layout', 1, True), Extension('VK_KHR_sampler_mirror_clamp_to_edge', 1, True), + Extension('VK_KHR_sampler_ycbcr_conversion', 1, True), Extension('VK_KHR_shader_draw_parameters', 1, True), Extension('VK_KHR_storage_buffer_storage_class', 1, True), Extension('VK_KHR_surface', 25, 'ANV_HAS_SURFACE'), diff --git a/src/intel/vulkan/anv_formats.c b/src/intel/vulkan/anv_formats.c index 3a941d4bd06..8c22d1c9e1b 100644 --- a/src/intel/vulkan/anv_formats.c +++ b/src/intel/vulkan/anv_formats.c @@ -999,3 +999,62 @@ void anv_GetPhysicalDeviceExternalBufferPropertiesKHR( pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryPropertiesKHR) {0}; } + +VkResult anv_CreateSamplerYcbcrConversionKHR( + VkDevice _device, + const VkSamplerYcbcrConversionCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSamplerYcbcrConversionKHR* pYcbcrConversion) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_ycbcr_conversion *conversion; + + assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR); + + conversion = vk_alloc2(&device->alloc, pAllocator, sizeof(*conversion), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!conversion) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + memset(conversion, 0, sizeof(*conversion)); + + conversion->format = anv_get_format(pCreateInfo->format); + conversion->ycbcr_model = pCreateInfo->ycbcrModel; + conversion->ycbcr_range = pCreateInfo->ycbcrRange; + conversion->mapping[0] = pCreateInfo->components.r; + conversion->mapping[1] = pCreateInfo->components.g; + conversion->mapping[2] = pCreateInfo->components.b; + conversion->mapping[3] = pCreateInfo->components.a; + conversion->chroma_offsets[0] = pCreateInfo->xChromaOffset; + conversion->chroma_offsets[1] = pCreateInfo->yChromaOffset; + conversion->chroma_filter = pCreateInfo->chromaFilter; + + bool has_chroma_subsampled = false; + for (uint32_t p = 0; p < conversion->format->n_planes; p++) { + if (conversion->format->planes[p].has_chroma && + (conversion->format->planes[p].denominator_scales[0] > 1 || + conversion->format->planes[p].denominator_scales[1] > 1)) + has_chroma_subsampled = true; + } + conversion->chroma_reconstruction = has_chroma_subsampled && + (conversion->chroma_offsets[0] == VK_CHROMA_LOCATION_COSITED_EVEN_KHR || + conversion->chroma_offsets[1] == VK_CHROMA_LOCATION_COSITED_EVEN_KHR); + + *pYcbcrConversion = anv_ycbcr_conversion_to_handle(conversion); + + return VK_SUCCESS; +} + +void anv_DestroySamplerYcbcrConversionKHR( + VkDevice _device, + VkSamplerYcbcrConversionKHR YcbcrConversion, + const VkAllocationCallbacks* pAllocator) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + ANV_FROM_HANDLE(anv_ycbcr_conversion, conversion, YcbcrConversion); + + if (!conversion) + return; + + vk_free2(&device->alloc, pAllocator, conversion); +} diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index 6b3b70803d0..2865650f1d4 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -524,6 +524,7 @@ anv_image_create(VkDevice _device, image->samples = pCreateInfo->samples; image->usage = pCreateInfo->usage; image->tiling = pCreateInfo->tiling; + image->disjoint = pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT_KHR; const struct anv_format *format = anv_get_format(image->vk_format); assert(format != NULL); @@ -575,11 +576,12 @@ anv_DestroyImage(VkDevice _device, VkImage _image, vk_free2(&device->alloc, pAllocator, image); } -static VkResult anv_image_bind_memory_plane(struct anv_device *device, - struct anv_image *image, - uint32_t plane, - struct anv_device_memory *memory, - uint32_t memory_offset) +static void +anv_image_plane_bind_memory(struct anv_device *device, + struct anv_image *image, + uint32_t plane, + struct anv_device_memory *memory, + uint32_t memory_offset) { if (memory) { image->planes[plane].bo = memory->bo; @@ -588,8 +590,6 @@ static VkResult anv_image_bind_memory_plane(struct anv_device *device, image->planes[plane].bo = NULL; image->planes[plane].bo_offset = 0; } - - return VK_SUCCESS; } VkResult anv_BindImageMemory( @@ -605,17 +605,15 @@ VkResult anv_BindImageMemory( uint32_t plane, aspect_bit; anv_foreach_plane_aspect_bit(plane, aspect_bit, image->aspects, image->aspects) { - VkResult result = anv_image_bind_memory_plane(device, image, plane, - mem, memoryOffset); - if (result != VK_SUCCESS) - return vk_error(result); + anv_image_plane_bind_memory(device, image, plane, + mem, memoryOffset); } return VK_SUCCESS; } VkResult anv_BindImageMemory2KHR( - VkDevice device, + VkDevice _device, uint32_t bindInfoCount, const VkBindImageMemoryInfoKHR* pBindInfos) { @@ -625,18 +623,36 @@ VkResult anv_BindImageMemory2KHR( const VkBindImageMemoryInfoKHR *bind_info = &pBindInfos[i]; if (pBindInfos->pNext == NULL) { - result = anv_BindImageMemory(device, bind_info->image, + result = anv_BindImageMemory(_device, bind_info->image, bind_info->memory, bind_info->memoryOffset); } else { + ANV_FROM_HANDLE(anv_device, device, _device); + ANV_FROM_HANDLE(anv_device_memory, mem, bind_info->memory); + ANV_FROM_HANDLE(anv_image, image, bind_info->image); + vk_foreach_struct_const(s, bind_info->pNext) { switch (s->sType) { + case VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR: { + const VkBindImagePlaneMemoryInfoKHR *plane_info = + (const VkBindImagePlaneMemoryInfoKHR *) s; + uint32_t plane = + anv_image_aspect_to_plane(image->aspects, + plane_info->planeAspect); + + anv_image_plane_bind_memory(device, image, plane, + mem, bind_info->memoryOffset); + break; + } default: anv_debug_ignored_stype(s->sType); break; } } } + + if (result != VK_SUCCESS) + return vk_error(result); } return result; diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index cb324a3995e..0f1f008a897 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2362,6 +2362,9 @@ struct anv_image { VkDeviceSize size; uint32_t alignment; + /* Whether the image is made of several underlying buffer objects rather a + * single one with different offsets. + */ bool disjoint; /** @@ -2881,6 +2884,7 @@ ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_sampler, VkSampler) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_semaphore, VkSemaphore) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_shader_module, VkShaderModule) ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_debug_report_callback, VkDebugReportCallbackEXT) +ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_ycbcr_conversion, VkSamplerYcbcrConversionKHR) /* Gen-specific function declarations */ #ifdef genX diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c index 91da05cddbf..b7e4e5bceab 100644 --- a/src/intel/vulkan/genX_state.c +++ b/src/intel/vulkan/genX_state.c @@ -33,6 +33,8 @@ #include "genxml/gen_macros.h" #include "genxml/genX_pack.h" +#include "vk_util.h" + VkResult genX(init_device_state)(struct anv_device *device) { @@ -176,12 +178,44 @@ VkResult genX(CreateSampler)( uint32_t border_color_offset = device->border_colors.offset + pCreateInfo->borderColor * 64; - bool enable_min_filter_addr_rounding = - pCreateInfo->minFilter != VK_FILTER_NEAREST; - bool enable_mag_filter_addr_rounding = - pCreateInfo->magFilter != VK_FILTER_NEAREST; + vk_foreach_struct(ext, pCreateInfo->pNext) { + switch (ext->sType) { + case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR: { + VkSamplerYcbcrConversionInfoKHR *pSamplerConversion = + (VkSamplerYcbcrConversionInfoKHR *) ext; + ANV_FROM_HANDLE(anv_ycbcr_conversion, conversion, + pSamplerConversion->conversion); + + if (conversion == NULL) + break; + + sampler->n_planes = conversion->format->n_planes; + sampler->conversion = conversion; + break; + } + default: + anv_debug_ignored_stype(ext->sType); + break; + } + } for (unsigned p = 0; p < sampler->n_planes; p++) { + const bool plane_has_chroma = + sampler->conversion && sampler->conversion->format->planes[p].has_chroma; + const VkFilter min_filter = + plane_has_chroma ? sampler->conversion->chroma_filter : pCreateInfo->minFilter; + const VkFilter mag_filter = + plane_has_chroma ? sampler->conversion->chroma_filter : pCreateInfo->magFilter; + const bool enable_min_filter_addr_rounding = min_filter != VK_FILTER_NEAREST; + const bool enable_mag_filter_addr_rounding = mag_filter != VK_FILTER_NEAREST; + /* From Broadwell PRM, SAMPLER_STATE: + * "Mip Mode Filter must be set to MIPFILTER_NONE for Planar YUV surfaces." + */ + const uint32_t mip_filter_mode = + (sampler->conversion && + isl_format_is_yuv(sampler->conversion->format->planes[0].isl_format)) ? + MIPFILTER_NONE : vk_to_gen_mipmap_mode[pCreateInfo->mipmapMode]; + struct GENX(SAMPLER_STATE) sampler_state = { .SamplerDisable = false, .TextureBorderColorMode = DX10OGL, @@ -195,11 +229,9 @@ VkResult genX(CreateSampler)( #if GEN_GEN == 8 .BaseMipLevel = 0.0, #endif - .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipmapMode], - .MagModeFilter = vk_to_gen_tex_filter(pCreateInfo->magFilter, - pCreateInfo->anisotropyEnable), - .MinModeFilter = vk_to_gen_tex_filter(pCreateInfo->minFilter, - pCreateInfo->anisotropyEnable), + .MipModeFilter = mip_filter_mode, + .MagModeFilter = vk_to_gen_tex_filter(mag_filter, pCreateInfo->anisotropyEnable), + .MinModeFilter = vk_to_gen_tex_filter(min_filter, pCreateInfo->anisotropyEnable), .TextureLODBias = anv_clamp_f(pCreateInfo->mipLodBias, -16, 15.996), .AnisotropicAlgorithm = EWAApproximation, .MinLOD = anv_clamp_f(pCreateInfo->minLod, 0, 14), -- 2.14.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev