Skip to content

Commit

Permalink
vkd3d: Add workaround to explicitly clear memory on 6.10+ amdgpu.
Browse files Browse the repository at this point in the history
It seems like there is a bug with the new zerovram code in kernel.
Manifests as test failures in specific circumstances.

Signed-off-by: Hans-Kristian Arntzen <[email protected]>
  • Loading branch information
HansKristian-Work committed Dec 4, 2024
1 parent 4b9fc10 commit 73e59ce
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 7 deletions.
28 changes: 28 additions & 0 deletions libs/vkd3d/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -2998,6 +2998,32 @@ static HRESULT vkd3d_select_queues(const struct d3d12_device *device,
return S_OK;
}

static void d3d12_device_init_workarounds(struct d3d12_device *device)
{
uint32_t major, minor, patch;

if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_SKIP_DRIVER_WORKAROUNDS)
return;

if (device->device_info.properties2.properties.vendorID != 0x1002)
return;

if (vkd3d_get_linux_kernel_version(&major, &minor, &patch))
{
/* 6.10 amdgpu kernel changes the clear vram code to do background clears instead
* of on-demand clearing. This seems to have bugs, and we have been able to observe
* non-zeroed VRAM coming from the affected kernels.
* This workaround needs to be in place until we have confirmed a fix in upstream kernel. */
INFO("Detected Linux kernel version %u.%u.%u\n", major, minor, patch);

if (major > 6 || (major == 6 && minor >= 10))
{
INFO("AMDGPU broken kernel detected. Enabling manual memory clearing path.\n");
device->workarounds.amdgpu_broken_clearvram = true;
}
}
}

static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
const struct vkd3d_device_create_info *create_info)
{
Expand Down Expand Up @@ -3136,6 +3162,8 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
device->vk_info.extension_count = device_info.enabledExtensionCount;
device->vk_info.extension_names = extensions;

d3d12_device_init_workarounds(device);

TRACE("Created Vulkan device %p.\n", vk_device);

return hr;
Expand Down
14 changes: 7 additions & 7 deletions libs/vkd3d/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -1801,9 +1801,12 @@ static HRESULT vkd3d_suballocate_memory(struct d3d12_device *device, struct vkd3
return hr;
}

static inline bool vkd3d_driver_implicitly_clears(VkDriverId driver_id)
static inline bool vkd3d_driver_implicitly_clears(struct d3d12_device *device)
{
switch (driver_id)
if (device->workarounds.amdgpu_broken_clearvram)
return false;

switch (device->device_info.vulkan_1_2_properties.driverID)
{
/* Known to pass test_stress_suballocation which hits this path. */
case VK_DRIVER_ID_MESA_RADV:
Expand Down Expand Up @@ -1832,8 +1835,7 @@ bool vkd3d_allocate_image_memory_prefers_dedicated(struct d3d12_device *device,
/* If we don't need to sub-allocate, and we don't need to clear any buffers
* there is no need to allocate a GLOBAL_BUFFER. */
return requirements->size >= VKD3D_VA_BLOCK_SIZE &&
(vkd3d_driver_implicitly_clears(device->device_info.vulkan_1_2_properties.driverID) ||
(heap_flags & D3D12_HEAP_FLAG_CREATE_NOT_ZEROED));
(vkd3d_driver_implicitly_clears(device) || (heap_flags & D3D12_HEAP_FLAG_CREATE_NOT_ZEROED));
}

static bool vkd3d_memory_info_allow_suballocate(struct d3d12_device *device,
Expand Down Expand Up @@ -1891,9 +1893,7 @@ HRESULT vkd3d_allocate_memory(struct d3d12_device *device, struct vkd3d_memory_a
* This is relying on implementation details.
* RADV definitely does this, and it seems like NV also does it.
* TODO: an extension for this would be nice. */
implementation_implicitly_clears =
vkd3d_driver_implicitly_clears(device->device_info.vulkan_1_2_properties.driverID) &&
!suballocate;
implementation_implicitly_clears = vkd3d_driver_implicitly_clears(device) && !suballocate;

needs_clear = !implementation_implicitly_clears &&
!(info->heap_flags & D3D12_HEAP_FLAG_CREATE_NOT_ZEROED) &&
Expand Down
5 changes: 5 additions & 0 deletions libs/vkd3d/vkd3d_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -4981,6 +4981,11 @@ struct d3d12_device

struct vkd3d_device_swapchain_info swapchain_info;
struct vkd3d_device_frame_markers frame_markers;

struct
{
bool amdgpu_broken_clearvram;
} workarounds;
};

HRESULT d3d12_device_create(struct vkd3d_instance *instance,
Expand Down

0 comments on commit 73e59ce

Please sign in to comment.