hasvk: Add host_image_copy, H.264 encode and a batch of gen7 fixes.

Squashed work that had been sitting in the working tree. Grouped by area:

Extensions
  VK_EXT_host_image_copy, with a MEMCPY_BIT path that reads and writes the
  image's own tiled layout, VkSubresourceHostMemcpySizeEXT filled in, and
  VkHostImageCopyDevicePerformanceQueryEXT answered.  Depth/stencil and
  non-power-of-two bpb stay NotSupported.
  VK_EXT_pipeline_robustness, VK_KHR_shader_float_controls2,
  VK_KHR_shader_subgroup_rotate, VK_EXT_vertex_input_dynamic_state,
  VK_EXT_conditional_rendering (an MI_PREDICATE path for gen7, which has no
  GPRs), custom_border_color, border_color_swizzle, map_memory2,
  load_store_op_none, depth_clamp_zero_one,
  dynamic_rendering_unused_attachments, index_type_uint8,
  line_rasterization, vertex_attribute_divisor, mutable_descriptor_type.

H.264 encode
  MFC command emission and a bitstream writer, driving intra-only encode
  through the video queue.  Video profile reporting was also corrected from
  270 combinations down to the 11 that actually exist.

Correctness
  gfx7 routes typed surface writes through the render cache, so
  VK_ACCESS_SHADER_WRITE barriers have to flush it -- without that, nothing a
  fragment shader stored was visible.
  nir_opt_algebraic's fadd->flrp fusion rules dropped signed zero; '~' only
  excludes nir_fp_exact, not preserve_signed_zero, so reflect() with a -0
  input came out wrong.  Guarded with (nsz).
  Stop advertising STORAGE_READ_WITHOUT_FORMAT: shaderStorageImageReadWithout-
  Format is false here, and since Vulkan 1.3 the per-format bit is what grants
  permission, so reporting it while rejecting the pipeline is a contradiction.
  gfx7's typed data port ignores SURFTYPE_NULL -- the null surface still has
  one addressable texel, which read and wrote graphics address zero.  Bounds
  check typed image access against the image param when nullDescriptor is
  enabled, the same trick lower_image_atomic_instr already used on IVB.
  Formats that require a sampler Y'CbCr conversion no longer report
  BLIT_SRC/BLIT_DST/STORAGE_IMAGE.  Video decode does not need them.
  Check the surface state allocations in emit_binding_table() and in the push
  descriptor path instead of writing through a NULL map in release builds.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
elwrclandClaude Opus 5 committed 2026-08-09 00:32:40 +03:00
1 parent 0e4983ca15
commit 636d2c2f70
28 files changed
+2666 -327

No files matched your search

+121 -30
View File
@@ -99,6 +99,7 @@ static const driOptionDescription anv_dri_options[] = {
static const struct debug_control debug_control[] = {
{ "video-decode", ANV_DEBUG_VIDEO_DECODE },
{ "video-debug", ANV_DEBUG_VIDEO_DEBUG },
{ "video-encode", ANV_DEBUG_VIDEO_ENCODE },
{ NULL, 0 }
};
@@ -206,7 +207,10 @@ get_device_extensions(const struct anv_physical_device *device,
const bool has_syncobj_wait =
(device->sync_syncobj_type.features & VK_SYNC_FEATURE_CPU_WAIT) != 0;
const bool video_decode = VIDEO_CODEC_H264DEC && ANV_DEBUG(VIDEO_DECODE);
/* Video extensions are advertised by default (not gated behind
* HASVK_DEBUG); the compile-time VIDEO_CODEC_* configuration still applies. */
const bool video_decode = VIDEO_CODEC_H264DEC;
const bool video_encode = VIDEO_CODEC_H264ENC;
*ext = (struct vk_device_extension_table) {
.KHR_8bit_storage = device->info.ver >= 8,
@@ -217,6 +221,7 @@ get_device_extensions(const struct anv_physical_device *device,
.KHR_create_renderpass2 = true,
.KHR_dedicated_allocation = true,
.KHR_deferred_host_operations = true,
.KHR_depth_clamp_zero_one = true,
.KHR_depth_stencil_resolve = true,
.KHR_descriptor_update_template = true,
.KHR_device_group = true,
@@ -233,6 +238,7 @@ get_device_extensions(const struct anv_physical_device *device,
.KHR_get_memory_requirements2 = true,
.KHR_image_format_list = true,
.KHR_imageless_framebuffer = true,
.KHR_load_store_op_none = true,
#ifdef ANV_USE_WSI_PLATFORM
.KHR_incremental_present = true,
#endif
@@ -264,10 +270,12 @@ get_device_extensions(const struct anv_physical_device *device,
.KHR_shader_expect_assume = true,
.KHR_shader_float16_int8 = device->info.ver >= 8 && !device->instance->no_16bit,
.KHR_shader_float_controls = true,
.KHR_shader_float_controls2 = true,
.KHR_shader_integer_dot_product = true,
.KHR_shader_non_semantic_info = true,
.KHR_shader_relaxed_extended_instruction = true,
.KHR_shader_subgroup_extended_types = device->info.ver >= 8,
.KHR_shader_subgroup_rotate = true,
.KHR_shader_subgroup_uniform_control_flow = true,
.KHR_shader_terminate_invocation = true,
.KHR_spirv_1_4 = true,
@@ -276,11 +284,13 @@ get_device_extensions(const struct anv_physical_device *device,
.KHR_swapchain = true,
.KHR_swapchain_mutable_format = true,
#endif
.KHR_video_queue = video_decode,
.KHR_video_queue = video_decode || video_encode,
.KHR_video_decode_queue = video_decode,
.KHR_video_decode_h264 = video_decode,
.KHR_video_maintenance1 = video_decode,
.KHR_video_maintenance2 = video_decode,
.KHR_video_encode_queue = video_encode,
.KHR_video_encode_h264 = video_encode,
.KHR_video_maintenance1 = video_decode || video_encode,
.KHR_video_maintenance2 = video_decode || video_encode,
.KHR_synchronization2 = true,
.KHR_timeline_semaphore = true,
.KHR_internally_synchronized_queues = true,
@@ -290,12 +300,12 @@ get_device_extensions(const struct anv_physical_device *device,
.KHR_workgroup_memory_explicit_layout = true,
.KHR_zero_initialize_workgroup_memory = true,
.EXT_4444_formats = true,
.EXT_border_color_swizzle = device->info.ver >= 8,
.EXT_border_color_swizzle = device->info.ver >= 7,
.EXT_buffer_device_address = device->has_a64_buffer_access,
.EXT_calibrated_timestamps = device->has_reg_timestamp,
.EXT_color_write_enable = true,
.EXT_conditional_rendering = device->info.verx10 >= 75,
.EXT_custom_border_color = device->info.ver >= 8,
.EXT_conditional_rendering = device->info.verx10 >= 70,
.EXT_custom_border_color = device->info.ver >= 7,
.EXT_debug_marker = true,
.EXT_depth_clamp_zero_one = true,
.EXT_depth_clamp_control = true,
@@ -304,6 +314,7 @@ get_device_extensions(const struct anv_physical_device *device,
#ifdef VK_USE_PLATFORM_DISPLAY_KHR
.EXT_display_control = true,
#endif
.EXT_dynamic_rendering_unused_attachments = true,
.EXT_extended_dynamic_state = true,
.EXT_extended_dynamic_state2 = true,
.EXT_external_memory_dma_buf = true,
@@ -312,14 +323,19 @@ get_device_extensions(const struct anv_physical_device *device,
INTEL_CONTEXT_MEDIUM_PRIORITY,
.EXT_global_priority_query = device->max_context_priority >=
INTEL_CONTEXT_MEDIUM_PRIORITY,
.EXT_host_image_copy = true,
.EXT_host_query_reset = true,
.EXT_image_2d_view_of_3d = true,
.EXT_image_robustness = true,
.EXT_image_drm_format_modifier = true,
.EXT_image_view_min_lod = true,
.EXT_index_type_uint8 = true,
.KHR_index_type_uint8 = true,
.EXT_inline_uniform_block = true,
.EXT_line_rasterization = true,
.KHR_line_rasterization = true,
.EXT_load_store_op_none = true,
.KHR_map_memory2 = true,
/* Enable the extension only if we have support on both the local &
* system memory
*/
@@ -329,6 +345,7 @@ get_device_extensions(const struct anv_physical_device *device,
.EXT_physical_device_drm = true,
.EXT_pipeline_creation_cache_control = true,
.EXT_pipeline_creation_feedback = true,
.EXT_pipeline_robustness = true,
.EXT_primitives_generated_query = true,
.EXT_primitive_topology_list_restart = true,
.EXT_private_data = true,
@@ -350,6 +367,8 @@ get_device_extensions(const struct anv_physical_device *device,
.EXT_tooling_info = true,
.EXT_transform_feedback = true,
.EXT_vertex_attribute_divisor = true,
.EXT_vertex_input_dynamic_state = true,
.KHR_vertex_attribute_divisor = true,
.EXT_ycbcr_image_arrays = true,
#if DETECT_OS_ANDROID
.ANDROID_external_memory_android_hardware_buffer = true,
@@ -364,6 +383,7 @@ get_device_extensions(const struct anv_physical_device *device,
.EXT_multi_draw = true,
.NV_compute_shader_derivatives = true,
.VALVE_mutable_descriptor_type = true,
.EXT_mutable_descriptor_type = true
};
}
@@ -511,6 +531,9 @@ get_features(const struct anv_physical_device *pdevice,
.formatA4R4G4B4 = true,
.formatA4B4G4R4 = false,
/* VK_EXT_host_image_copy */
.hostImageCopy = true,
/* VK_EXT_border_color_swizzle */
.borderColorSwizzle = true,
.borderColorSwizzleFromImage = true,
@@ -527,12 +550,12 @@ get_features(const struct anv_physical_device *pdevice,
.computeDerivativeGroupLinear = true,
/* VK_EXT_conditional_rendering */
.conditionalRendering = pdevice->info.verx10 >= 75,
.conditionalRendering = pdevice->info.verx10 >= 70,
.inheritedConditionalRendering = pdevice->info.verx10 >= 75,
/* VK_EXT_custom_border_color */
.customBorderColors = pdevice->info.ver >= 8,
.customBorderColorWithoutFormat = pdevice->info.ver >= 8,
.customBorderColors = pdevice->info.ver >= 7,
.customBorderColorWithoutFormat = pdevice->info.ver >= 7,
/* VK_EXT_depth_clamp_zero_one */
.depthClampZeroOne = true,
@@ -594,6 +617,9 @@ get_features(const struct anv_physical_device *pdevice,
.robustImageAccess2 = true,
.nullDescriptor = true,
/* VK_EXT_pipeline_robustness */
.pipelineRobustness = true,
/* VK_EXT_shader_atomic_float */
.shaderBufferFloat32Atomics = true,
.shaderBufferFloat32AtomicAdd = pdevice->info.has_lsc,
@@ -619,9 +645,16 @@ get_features(const struct anv_physical_device *pdevice,
/* VK_EXT_shader_module_identifier */
.shaderModuleIdentifier = true,
/* VK_KHR_shader_float_controls2 */
.shaderFloatControls2 = true,
/* VK_EXT_shader_replicated_composites */
.shaderReplicatedComposites = true,
/* VK_KHR_shader_subgroup_rotate */
.shaderSubgroupRotate = true,
.shaderSubgroupRotateClustered = true,
/* VK_KHR_shader_subgroup_uniform_control_flow */
.shaderSubgroupUniformControlFlow = true,
@@ -645,6 +678,9 @@ get_features(const struct anv_physical_device *pdevice,
/* VK_EXT_ycbcr_image_arrays */
.ycbcrImageArrays = true,
/* VK_EXT_dynamic_rendering_unused_attachments */
.dynamicRenderingUnusedAttachments = true,
/* VK_EXT_extended_dynamic_state */
.extendedDynamicState = true,
@@ -653,6 +689,9 @@ get_features(const struct anv_physical_device *pdevice,
.extendedDynamicState2LogicOp = true,
.extendedDynamicState2PatchControlPoints = false,
/* VK_EXT_vertex_input_dynamic_state */
.vertexInputDynamicState = true,
/* VK_EXT_multi_draw */
.multiDraw = true,
@@ -744,7 +783,9 @@ get_properties_1_1(const struct anv_physical_device *pdevice,
VK_SUBGROUP_FEATURE_BALLOT_BIT |
VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT |
VK_SUBGROUP_FEATURE_QUAD_BIT;
VK_SUBGROUP_FEATURE_QUAD_BIT |
VK_SUBGROUP_FEATURE_ROTATE_BIT_KHR |
VK_SUBGROUP_FEATURE_ROTATE_CLUSTERED_BIT_KHR;
if (pdevice->info.ver >= 8) {
/* TODO: There's no technical reason why these can't be made to
* work on gfx7 but they don't at the moment so it's best to leave
@@ -1215,6 +1256,22 @@ get_properties(const struct anv_physical_device *pdevice,
props->lineSubPixelPrecisionBits = 4;
}
/* VK_EXT_host_image_copy */
{
static const VkImageLayout host_copy_layouts[] = {
VK_IMAGE_LAYOUT_GENERAL,
};
props->copySrcLayoutCount = ARRAY_SIZE(host_copy_layouts);
props->pCopySrcLayouts = (VkImageLayout *)host_copy_layouts;
props->copyDstLayoutCount = ARRAY_SIZE(host_copy_layouts);
props->pCopyDstLayouts = (VkImageLayout *)host_copy_layouts;
props->identicalMemoryTypeRequirements = true;
memcpy(props->optimalTilingLayoutUUID, pdevice->driver_uuid,
VK_UUID_SIZE);
}
/* VK_EXT_multi_draw */
{
props->maxMultiDrawCount = 2048;
@@ -1238,6 +1295,21 @@ get_properties(const struct anv_physical_device *pdevice,
props->drmRenderMinor = pdevice->local_minor;
}
/* VK_EXT_pipeline_robustness */
{
/* Intel HW bounds-checks vertex fetch and image/texel access
* unconditionally, so the device default is robust for those; buffer
* access is unchecked unless robustBufferAccess is enabled. */
props->defaultRobustnessStorageBuffers =
VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT;
props->defaultRobustnessUniformBuffers =
VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT;
props->defaultRobustnessVertexInputs =
VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT;
props->defaultRobustnessImages =
VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2_EXT;
}
/* VK_EXT_provoking_vertex */
{
props->provokingVertexModePerPipeline = true;
@@ -1594,17 +1666,26 @@ anv_physical_device_init_queue_families(struct anv_physical_device *pdevice)
.engine_class = INTEL_ENGINE_CLASS_RENDER,
};
}
if (v_count > 0 && VIDEO_CODEC_H264DEC && ANV_DEBUG(VIDEO_DECODE)) {
/* Video queues are exposed by default (not gated behind HASVK_DEBUG);
* the compile-time VIDEO_CODEC_* configuration still applies. */
if (v_count > 0 && VIDEO_CODEC_H264DEC) {
pdevice->queue.families[family_count++] = (struct anv_queue_family) {
.queueFlags = VK_QUEUE_VIDEO_DECODE_BIT_KHR,
.queueCount = v_count,
.engine_class = INTEL_ENGINE_CLASS_VIDEO,
};
}
/* Increase count below when other families are added as a reminder to
if (v_count > 0 && VIDEO_CODEC_H264ENC) {
pdevice->queue.families[family_count++] = (struct anv_queue_family) {
.queueFlags = VK_QUEUE_VIDEO_ENCODE_BIT_KHR,
.queueCount = v_count,
.engine_class = INTEL_ENGINE_CLASS_VIDEO,
};
}
/* Increase count below when other families are added and
* increase the ANV_MAX_QUEUE_FAMILIES value.
*/
STATIC_ASSERT(ANV_MAX_QUEUE_FAMILIES >= 3);
STATIC_ASSERT(ANV_MAX_QUEUE_FAMILIES >= 4);
} else {
/* Default to a single render queue */
pdevice->queue.families[family_count++] = (struct anv_queue_family) {
@@ -2135,7 +2216,8 @@ void anv_GetPhysicalDeviceQueueFamilyProperties2(
* to write the query result to memory. The VCS seemingly
* cannot do a posted memory write. */
prop->queryResultStatusSupport =
(queue_family->queueFlags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) ?
(queue_family->queueFlags & (VK_QUEUE_VIDEO_DECODE_BIT_KHR |
VK_QUEUE_VIDEO_ENCODE_BIT_KHR)) ?
VK_FALSE : VK_TRUE;
break;
}
@@ -2145,6 +2227,9 @@ void anv_GetPhysicalDeviceQueueFamilyProperties2(
if (queue_family->queueFlags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) {
prop->videoCodecOperations =
VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR;
} else if (queue_family->queueFlags & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) {
prop->videoCodecOperations =
VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR;
}
break;
}
@@ -2684,7 +2769,7 @@ VkResult anv_CreateDevice(
if (result != VK_SUCCESS)
goto fail_general_state_pool;
if (device->info->ver >= 8) {
if (device->info->ver >= 7) {
/* The border color pointer is limited to 24 bits, so we need to make
* sure that any such color used at any point in the program doesn't
* exceed that limit.
@@ -2818,7 +2903,7 @@ VkResult anv_CreateDevice(
fail_instruction_state_pool:
anv_state_pool_finish(&device->instruction_state_pool);
fail_dynamic_state_pool:
if (device->info->ver >= 8)
if (device->info->ver >= 7)
anv_state_reserved_pool_finish(&device->custom_border_colors);
anv_state_pool_finish(&device->dynamic_state_pool);
fail_general_state_pool:
@@ -2870,7 +2955,7 @@ void anv_DestroyDevice(
/* We only need to free these to prevent valgrind errors. The backing
* BO will go away in a couple of lines so we don't actually leak.
*/
if (device->info->ver >= 8)
if (device->info->ver >= 7)
anv_state_reserved_pool_finish(&device->custom_border_colors);
anv_state_pool_free(&device->dynamic_state_pool, device->border_colors);
anv_state_pool_free(&device->dynamic_state_pool, device->slice_hash);
@@ -3355,8 +3440,11 @@ void anv_FreeMemory(
list_del(&mem->link);
pthread_mutex_unlock(&device->mutex);
if (mem->map)
anv_UnmapMemory(_device, _mem);
const VkMemoryUnmapInfoKHR unmap = {
.sType = VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO_KHR,
.memory = _mem,
};
anv_UnmapMemory2KHR(_device, &unmap);
p_atomic_add(&device->physical->memory.heaps[mem->type->heapIndex].used,
-mem->bo->size);
@@ -3371,16 +3459,17 @@ void anv_FreeMemory(
vk_object_free(&device->vk, pAllocator, mem);
}
VkResult anv_MapMemory(
VkResult anv_MapMemory2KHR(
VkDevice _device,
VkDeviceMemory _memory,
VkDeviceSize offset,
VkDeviceSize size,
VkMemoryMapFlags flags,
const VkMemoryMapInfoKHR* pMemoryMapInfo,
void** ppData)
{
ANV_FROM_HANDLE(anv_device, device, _device);
ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
ANV_FROM_HANDLE(anv_device_memory, mem, pMemoryMapInfo->memory);
const VkDeviceSize offset = pMemoryMapInfo->offset;
VkDeviceSize size = pMemoryMapInfo->size;
const VkMemoryMapFlags flags = pMemoryMapInfo->flags;
if (mem == NULL) {
*ppData = NULL;
@@ -3462,21 +3551,23 @@ VkResult anv_MapMemory(
return VK_SUCCESS;
}
void anv_UnmapMemory(
VkResult anv_UnmapMemory2KHR(
VkDevice _device,
VkDeviceMemory _memory)
const VkMemoryUnmapInfoKHR* pMemoryUnmapInfo)
{
ANV_FROM_HANDLE(anv_device, device, _device);
ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
ANV_FROM_HANDLE(anv_device_memory, mem, pMemoryUnmapInfo->memory);
if (mem == NULL || mem->host_ptr)
return;
return VK_SUCCESS;
anv_device_unmap_bo(device, mem->bo, mem->map, mem->map_size);
mem->map = NULL;
mem->map_size = 0;
mem->map_delta = 0;
return VK_SUCCESS;
}
VkResult anv_FlushMappedMemoryRanges(