vkd3d: Refactor out memory topology queries.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
parent
abdaeb136d
commit
cec741706d
|
@ -5875,80 +5875,92 @@ HRESULT d3d12_query_heap_create(struct d3d12_device *device, const D3D12_QUERY_H
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t vkd3d_memory_info_find_global_mask(struct d3d12_device *device)
|
struct vkd3d_memory_topology
|
||||||
{
|
{
|
||||||
/* Never allow memory types from any PCI-pinned heap.
|
VkDeviceSize largest_device_local_heap_size;
|
||||||
* If we allow it, it might end up being used as a fallback memory type, which will cause severe instabilities.
|
VkDeviceSize largest_host_only_heap_size;
|
||||||
* These types should only be used in a controlled fashion. */
|
uint32_t largest_device_local_heap_index;
|
||||||
VkDeviceSize largest_device_local_heap_size = 0;
|
uint32_t largest_host_only_heap_index;
|
||||||
VkDeviceSize largest_host_only_heap_size = 0;
|
uint32_t device_local_heap_count;
|
||||||
uint32_t largest_device_local_heap_index = 0;
|
uint32_t host_only_heap_count;
|
||||||
uint32_t largest_host_only_heap_index = 0;
|
|
||||||
uint32_t device_local_heap_count = 0;
|
|
||||||
uint32_t host_only_heap_count = 0;
|
|
||||||
bool exists_device_only_type;
|
bool exists_device_only_type;
|
||||||
VkMemoryPropertyFlags flags;
|
|
||||||
bool exists_host_only_type;
|
bool exists_host_only_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void vkd3d_memory_info_get_topology(struct vkd3d_memory_topology *topology,
|
||||||
|
struct d3d12_device *device)
|
||||||
|
{
|
||||||
|
VkMemoryPropertyFlags flags;
|
||||||
VkDeviceSize heap_size;
|
VkDeviceSize heap_size;
|
||||||
uint32_t heap_index;
|
uint32_t heap_index;
|
||||||
uint32_t i, mask;
|
unsigned int i;
|
||||||
|
|
||||||
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_UPLOAD_HVV)
|
memset(topology, 0, sizeof(*topology));
|
||||||
return UINT32_MAX;
|
|
||||||
|
|
||||||
for (i = 0; i < device->memory_properties.memoryHeapCount; i++)
|
for (i = 0; i < device->memory_properties.memoryHeapCount; i++)
|
||||||
{
|
{
|
||||||
heap_size = device->memory_properties.memoryHeaps[i].size;
|
heap_size = device->memory_properties.memoryHeaps[i].size;
|
||||||
if (device->memory_properties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
|
if (device->memory_properties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
|
||||||
{
|
{
|
||||||
if (heap_size > largest_device_local_heap_size)
|
if (heap_size > topology->largest_device_local_heap_size)
|
||||||
{
|
{
|
||||||
largest_device_local_heap_index = i;
|
topology->largest_device_local_heap_index = i;
|
||||||
largest_device_local_heap_size = heap_size;
|
topology->largest_device_local_heap_size = heap_size;
|
||||||
}
|
}
|
||||||
device_local_heap_count++;
|
topology->device_local_heap_count++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (heap_size > largest_host_only_heap_size)
|
if (heap_size > topology->largest_host_only_heap_size)
|
||||||
{
|
{
|
||||||
largest_host_only_heap_index = i;
|
topology->largest_host_only_heap_index = i;
|
||||||
largest_host_only_heap_size = heap_size;
|
topology->largest_host_only_heap_size = heap_size;
|
||||||
}
|
}
|
||||||
host_only_heap_count++;
|
topology->host_only_heap_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < device->memory_properties.memoryTypeCount; i++)
|
||||||
|
{
|
||||||
|
flags = device->memory_properties.memoryTypes[i].propertyFlags;
|
||||||
|
heap_index = device->memory_properties.memoryTypes[i].heapIndex;
|
||||||
|
|
||||||
|
if (heap_index == topology->largest_device_local_heap_index &&
|
||||||
|
(flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0 &&
|
||||||
|
(flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)
|
||||||
|
{
|
||||||
|
topology->exists_device_only_type = true;
|
||||||
|
}
|
||||||
|
else if (heap_index == topology->largest_host_only_heap_index &&
|
||||||
|
(flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) == 0 &&
|
||||||
|
(flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
|
||||||
|
{
|
||||||
|
topology->exists_host_only_type = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t vkd3d_memory_info_find_global_mask(const struct vkd3d_memory_topology *topology, struct d3d12_device *device)
|
||||||
|
{
|
||||||
|
/* Never allow memory types from any PCI-pinned heap.
|
||||||
|
* If we allow it, it might end up being used as a fallback memory type, which will cause severe instabilities.
|
||||||
|
* These types should only be used in a controlled fashion. */
|
||||||
|
VkMemoryPropertyFlags flags;
|
||||||
|
uint32_t heap_index;
|
||||||
|
uint32_t i, mask;
|
||||||
|
|
||||||
|
if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_UPLOAD_HVV)
|
||||||
|
return UINT32_MAX;
|
||||||
|
|
||||||
/* If we only have one device local heap, or no host-only heaps, there is nothing to do. */
|
/* If we only have one device local heap, or no host-only heaps, there is nothing to do. */
|
||||||
if (device_local_heap_count <= 1 || host_only_heap_count == 0)
|
if (topology->device_local_heap_count <= 1 || topology->host_only_heap_count == 0)
|
||||||
return UINT32_MAX;
|
return UINT32_MAX;
|
||||||
|
|
||||||
/* Verify that there exists a DEVICE_LOCAL type that is not HOST_VISIBLE on this device
|
/* Verify that there exists a DEVICE_LOCAL type that is not HOST_VISIBLE on this device
|
||||||
* which maps to the largest device local heap. That way, it is safe to mask out all memory types which are
|
* which maps to the largest device local heap. That way, it is safe to mask out all memory types which are
|
||||||
* DEVICE_LOCAL | HOST_VISIBLE.
|
* DEVICE_LOCAL | HOST_VISIBLE.
|
||||||
* Similarly, there must exist a host-only type. */
|
* Similarly, there must exist a host-only type. */
|
||||||
exists_device_only_type = false;
|
if (!topology->exists_device_only_type || !topology->exists_host_only_type)
|
||||||
exists_host_only_type = false;
|
|
||||||
for (i = 0; i < device->memory_properties.memoryTypeCount; i++)
|
|
||||||
{
|
|
||||||
flags = device->memory_properties.memoryTypes[i].propertyFlags;
|
|
||||||
heap_index = device->memory_properties.memoryTypes[i].heapIndex;
|
|
||||||
|
|
||||||
if (heap_index == largest_device_local_heap_index &&
|
|
||||||
(flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0 &&
|
|
||||||
(flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0)
|
|
||||||
{
|
|
||||||
exists_device_only_type = true;
|
|
||||||
}
|
|
||||||
else if (heap_index == largest_host_only_heap_index &&
|
|
||||||
(flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) == 0 &&
|
|
||||||
(flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
|
|
||||||
{
|
|
||||||
exists_host_only_type = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!exists_device_only_type || !exists_host_only_type)
|
|
||||||
return UINT32_MAX;
|
return UINT32_MAX;
|
||||||
|
|
||||||
/* Mask out any memory types which are deemed problematic. */
|
/* Mask out any memory types which are deemed problematic. */
|
||||||
|
@ -5959,8 +5971,8 @@ static uint32_t vkd3d_memory_info_find_global_mask(struct d3d12_device *device)
|
||||||
flags = device->memory_properties.memoryTypes[i].propertyFlags;
|
flags = device->memory_properties.memoryTypes[i].propertyFlags;
|
||||||
heap_index = device->memory_properties.memoryTypes[i].heapIndex;
|
heap_index = device->memory_properties.memoryTypes[i].heapIndex;
|
||||||
|
|
||||||
if (heap_index != largest_device_local_heap_index &&
|
if (heap_index != topology->largest_device_local_heap_index &&
|
||||||
heap_index != largest_host_only_heap_index &&
|
heap_index != topology->largest_host_only_heap_index &&
|
||||||
(flags & pinned_mask) == pinned_mask)
|
(flags & pinned_mask) == pinned_mask)
|
||||||
{
|
{
|
||||||
mask |= 1u << i;
|
mask |= 1u << i;
|
||||||
|
@ -5982,6 +5994,7 @@ HRESULT vkd3d_memory_info_init(struct vkd3d_memory_info *info,
|
||||||
{
|
{
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||||
VkMemoryRequirements memory_requirements;
|
VkMemoryRequirements memory_requirements;
|
||||||
|
struct vkd3d_memory_topology topology;
|
||||||
VkBufferCreateInfo buffer_info;
|
VkBufferCreateInfo buffer_info;
|
||||||
uint32_t sampled_type_mask_cpu;
|
uint32_t sampled_type_mask_cpu;
|
||||||
VkImageCreateInfo image_info;
|
VkImageCreateInfo image_info;
|
||||||
|
@ -5995,7 +6008,8 @@ HRESULT vkd3d_memory_info_init(struct vkd3d_memory_info *info,
|
||||||
VkResult vr;
|
VkResult vr;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
info->global_mask = vkd3d_memory_info_find_global_mask(device);
|
vkd3d_memory_info_get_topology(&topology, device);
|
||||||
|
info->global_mask = vkd3d_memory_info_find_global_mask(&topology, device);
|
||||||
|
|
||||||
if (pthread_mutex_init(&info->budget_lock, NULL) != 0)
|
if (pthread_mutex_init(&info->budget_lock, NULL) != 0)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
Loading…
Reference in New Issue