Signed-off-by: Lionel Landwerlin <lionel.g.landwer...@intel.com> --- src/intel/vulkan/anv_device.c | 51 ++++++++++++++++++++++++++++++-- src/intel/vulkan/anv_extensions.py | 1 + src/intel/vulkan/anv_formats.c | 59 ++++++++++++++++++++++++++++++++++++++ src/intel/vulkan/anv_image.c | 24 ++++++++++++++-- src/intel/vulkan/anv_private.h | 4 +++ src/intel/vulkan/genX_state.c | 51 ++++++++++++++++++++++++++------ 6 files changed, 177 insertions(+), 13 deletions(-)
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 4b30c0005fd..66187577e12 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; @@ -1818,8 +1825,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 cb0e36b7233..21fd3ff07bd 100644 --- a/src/intel/vulkan/anv_extensions.py +++ b/src/intel/vulkan/anv_extensions.py @@ -67,6 +67,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, True), diff --git a/src/intel/vulkan/anv_formats.c b/src/intel/vulkan/anv_formats.c index a8e9298a058..90668b71cb5 100644 --- a/src/intel/vulkan/anv_formats.c +++ b/src/intel/vulkan/anv_formats.c @@ -995,3 +995,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 26cb7273eef..368dcc8acbc 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -459,6 +459,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); @@ -583,7 +584,7 @@ VkResult anv_BindImageMemory( } VkResult anv_BindImageMemory2KHR( - VkDevice device, + VkDevice _device, uint32_t bindInfoCount, const VkBindImageMemoryInfoKHR* pBindInfos) { @@ -593,18 +594,37 @@ 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); + + result = + anv_image_bind_memory_plane(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 19e4e1c0916..a5f51dac3a2 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -2347,6 +2347,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; /** @@ -2826,6 +2829,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 91e180bc7e4..d073395ad98 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) { @@ -177,12 +179,45 @@ 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->nb_planes = conversion->format->n_planes; + sampler->conversion = conversion; + break; + } + default: + anv_debug_ignored_stype(ext->sType); + break; + } + } + for (unsigned p = 0; p < sampler->nb_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, @@ -196,11 +231,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.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev