diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 591a384d5c2..870ecc5c04d 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -708,11 +708,26 @@ VkResult anv_CreateDevice( 0 /* explicit_address */, &device->dummy_aux_bo); if (result != VK_SUCCESS) - goto fail_workaround_bo; + goto fail_alloc_device_bo; device->isl_dev.dummy_aux_address = device->dummy_aux_bo->offset; } + /* Programming note from MI_MEM_FENCE specification: + * + * Software must ensure STATE_SYSTEM_MEM_FENCE_ADDRESS command is + * programmed prior to programming this command. + * + * HAS 1607240579 then provides the size information: 4K + */ + if (device->info->verx10 >= 200) { + result = anv_device_alloc_bo(device, "mem_fence", 4096, + ANV_BO_ALLOC_NO_LOCAL_MEM, 0, + &device->mem_fence_bo); + if (result != VK_SUCCESS) + goto fail_alloc_device_bo; + } + struct anv_address wa_addr = (struct anv_address) { .bo = device->workaround_bo, }; @@ -762,7 +777,7 @@ VkResult anv_CreateDevice( 0 /* explicit_address */, &device->ray_query_bo[0]); if (result != VK_SUCCESS) - goto fail_dummy_aux_bo; + goto fail_alloc_device_bo; /* We need a separate ray query bo for CCS engine with Wa_14022863161. */ if (intel_needs_workaround(device->isl_dev.info, 14022863161) && @@ -1039,10 +1054,11 @@ VkResult anv_CreateDevice( if (device->ray_query_bo[i]) anv_device_release_bo(device, device->ray_query_bo[i]); } - fail_dummy_aux_bo: + fail_alloc_device_bo: + if (device->mem_fence_bo) + anv_device_release_bo(device, device->mem_fence_bo); if (device->dummy_aux_bo) anv_device_release_bo(device, device->dummy_aux_bo); - fail_workaround_bo: anv_device_release_bo(device, device->workaround_bo); fail_surface_aux_map_pool: if (device->info->has_aux_map) { @@ -1195,6 +1211,8 @@ void anv_DestroyDevice( anv_device_release_bo(device, device->workaround_bo); if (device->dummy_aux_bo) anv_device_release_bo(device, device->dummy_aux_bo); + if (device->mem_fence_bo) + anv_device_release_bo(device, device->mem_fence_bo); anv_device_release_bo(device, device->trivial_batch_bo); if (device->info->has_aux_map) { diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index c8dbb5a8e67..bb5bcc9f3af 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1932,6 +1932,7 @@ struct anv_device { struct anv_address workaround_address; struct anv_bo * dummy_aux_bo; + struct anv_bo * mem_fence_bo; /** * Workarounds for game bugs. diff --git a/src/intel/vulkan/genX_init_state.c b/src/intel/vulkan/genX_init_state.c index 2c1764ee9c0..b0779b494cb 100644 --- a/src/intel/vulkan/genX_init_state.c +++ b/src/intel/vulkan/genX_init_state.c @@ -182,6 +182,17 @@ genX(emit_slice_hashing_state)(struct anv_device *device, #endif } +static void +state_system_mem_fence_address_emit(struct anv_device *device, struct anv_batch *batch) +{ +#if GFX_VERx10 >= 200 + struct anv_address addr = { .bo = device->mem_fence_bo }; + anv_batch_emit(batch, GENX(STATE_SYSTEM_MEM_FENCE_ADDRESS), mem_fence_addr) { + mem_fence_addr.SystemMemoryFenceAddress = addr; + } +#endif +} + static void init_common_queue_state(struct anv_queue *queue, struct anv_batch *batch) { @@ -356,6 +367,8 @@ init_common_queue_state(struct anv_queue *queue, struct anv_batch *batch) } } #endif + + state_system_mem_fence_address_emit(device, batch); } #if GFX_VER >= 20 @@ -840,6 +853,8 @@ init_copy_video_queue_state(struct anv_queue *queue) assert(!queue->device->info->has_aux_map); #endif + state_system_mem_fence_address_emit(device, batch); + if (batch->start != batch->next) { anv_batch_emit(batch, GENX(MI_BATCH_BUFFER_END), bbe);