Skip to content

Commit

Permalink
vkd3d: Attempt workaround to redirect NULL sparse tiles to dummy page.
Browse files Browse the repository at this point in the history
Signed-off-by: Hans-Kristian Arntzen <[email protected]>
  • Loading branch information
HansKristian-Work committed Jan 29, 2025
1 parent b1bd9e1 commit 20313f1
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 5 deletions.
1 change: 1 addition & 0 deletions include/vkd3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ extern "C" {
#define VKD3D_CONFIG_FLAG_NO_GPU_UPLOAD_HEAP (1ull << 55)
#define VKD3D_CONFIG_FLAG_ONE_TIME_SUBMIT (1ull << 56)
#define VKD3D_CONFIG_FLAG_SKIP_NULL_SPARSE_TILES (1ull << 57)
#define VKD3D_CONFIG_FLAG_DUMMY_NULL_SPARSE_TILES (1ull << 58)

struct vkd3d_instance;

Expand Down
17 changes: 15 additions & 2 deletions libs/vkd3d/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -17514,8 +17514,21 @@ static void STDMETHODCALLTYPE d3d12_command_queue_UpdateTileMappings(ID3D12Comma

if (range_flag == D3D12_TILE_RANGE_FLAG_NULL)
{
bind->vk_memory = VK_NULL_HANDLE;
bind->vk_offset = 0;
if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_DUMMY_NULL_SPARSE_TILES) &&
command_queue->device->workarounds.amdgpu_broken_null_tile_mapping)
{
/* We have a convenient dummy BO already. It will also be allocated in 32-bit VA range,
* so it's easy to detect binds to it in RADV bo history.
* If we didn't use descriptor buffers for whatever reason we'll get the default NULL mapping behavior
* which is fine, since this is such a targeted workaround. */
bind->vk_memory = command_queue->device->global_descriptor_buffer.resource.device_allocation.vk_memory;
bind->vk_offset = 0;
}
else
{
bind->vk_memory = VK_NULL_HANDLE;
bind->vk_offset = 0;
}
}
else
{
Expand Down
6 changes: 4 additions & 2 deletions libs/vkd3d/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -608,9 +608,10 @@ static const struct vkd3d_instance_application_meta application_override[] = {
/* FFVII Rebirth (2909400).
* Game can destroy PSOs while they are in-flight.
* Also, add no-staggered since this is a UE title without the common workaround,
* although that only seems to matter when FSR/DLSS injectors are used. */
* although that only seems to matter when FSR/DLSS injectors are used.
* Also, attempt to workaround a painful amdgpu kernel bug with null sparse tiles. */
{ VKD3D_STRING_COMPARE_EXACT, "ff7rebirth_.exe",
VKD3D_CONFIG_FLAG_RETAIN_PSOS | VKD3D_CONFIG_FLAG_NO_STAGGERED_SUBMIT, 0 },
VKD3D_CONFIG_FLAG_RETAIN_PSOS | VKD3D_CONFIG_FLAG_NO_STAGGERED_SUBMIT | VKD3D_CONFIG_FLAG_DUMMY_NULL_SPARSE_TILES, 0 },
/* Unreal Engine catch-all. ReBAR is a massive uplift on RX 7600 for example in Wukong.
* AMD windows drivers also seem to have some kind of general app-opt for UE titles.
* Use no-staggered-submit by default on UE. We've only observed issues in Wukong here, but
Expand Down Expand Up @@ -1016,6 +1017,7 @@ static const struct vkd3d_debug_option vkd3d_config_options[] =
{"no_gpu_upload_heap", VKD3D_CONFIG_FLAG_NO_GPU_UPLOAD_HEAP},
{"one_time_submit", VKD3D_CONFIG_FLAG_ONE_TIME_SUBMIT},
{"skip_null_sparse_tiles", VKD3D_CONFIG_FLAG_SKIP_NULL_SPARSE_TILES},
{"dummy_null_sparse_tiles", VKD3D_CONFIG_FLAG_DUMMY_NULL_SPARSE_TILES},
};

static void vkd3d_config_flags_init_once(void)
Expand Down
9 changes: 8 additions & 1 deletion libs/vkd3d/resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -9109,6 +9109,7 @@ HRESULT vkd3d_global_descriptor_buffer_init(struct vkd3d_global_descriptor_buffe
struct d3d12_device *device)
{
VkBufferUsageFlags2KHR vk_usage_flags;
VkDeviceSize size;
HRESULT hr;

bool requires_offset_buffer = device->device_info.properties2.properties.limits.minStorageBufferOffsetAlignment > 4;
Expand Down Expand Up @@ -9164,8 +9165,14 @@ HRESULT vkd3d_global_descriptor_buffer_init(struct vkd3d_global_descriptor_buffe
/* Creates a default descriptor buffer we can use if the application does not bind anything.
* This might happen if a meta shader is used without any prior descriptor heap bound,
* and we need to use push descriptors with bufferlessPushDescriptors == VK_FALSE. */

/* The global descriptor buffer can be used as a DUMMY_NULL_TILE when a workaround is applied,
* so make sure it's at least 64K. In cases where it's relevant, we can rely on zerovram behavior too. */
size = (vkd3d_config_flags & VKD3D_CONFIG_FLAG_DUMMY_NULL_SPARSE_TILES) ?
VKD3D_TILE_SIZE : 4 * 1024;

if (FAILED(hr = vkd3d_create_buffer_explicit_usage(device, vk_usage_flags,
4 * 1024, "descriptor-buffer", &global_descriptor_buffer->resource.vk_buffer)))
size, "descriptor-buffer", &global_descriptor_buffer->resource.vk_buffer)))
{
return hr;
}
Expand Down

0 comments on commit 20313f1

Please sign in to comment.