Try to use cached memory for readbacks.

Speeds up nVidia readbacks by order of magnitude.
This commit is contained in:
Hans-Kristian Arntzen 2016-02-20 12:04:53 +01:00
parent 459c55989a
commit 5542427246
3 changed files with 23 additions and 7 deletions

View File

@ -62,17 +62,23 @@ uint32_t vulkan_find_memory_type(const VkPhysicalDeviceMemoryProperties *mem_pro
}
uint32_t vulkan_find_memory_type_fallback(const VkPhysicalDeviceMemoryProperties *mem_props,
uint32_t device_reqs, uint32_t host_reqs)
uint32_t device_reqs, uint32_t host_reqs_first, uint32_t host_reqs_second)
{
uint32_t i;
for (i = 0; i < VK_MAX_MEMORY_TYPES; i++)
{
if ((device_reqs & (1u << i)) &&
(mem_props->memoryTypes[i].propertyFlags & host_reqs) == host_reqs)
(mem_props->memoryTypes[i].propertyFlags & host_reqs_first) == host_reqs_first)
return i;
}
return vulkan_find_memory_type(mem_props, device_reqs, 0);
if (host_reqs_first == 0)
{
RARCH_ERR("[Vulkan]: Failed to find valid memory type. This should never happen.");
abort();
}
return vulkan_find_memory_type_fallback(mem_props, device_reqs, host_reqs_second, 0);
}
void vulkan_map_persistent_texture(VkDevice device, struct vk_texture *texture)
@ -181,13 +187,16 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
{
alloc.memoryTypeIndex = vulkan_find_memory_type_fallback(&vk->context->memory_properties,
mem_reqs.memoryTypeBits,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0);
}
else
{
/* This must exist. */
alloc.memoryTypeIndex = vulkan_find_memory_type(&vk->context->memory_properties,
VkMemoryPropertyFlags cached = type == VULKAN_TEXTURE_READBACK ?
VK_MEMORY_PROPERTY_HOST_CACHED_BIT : 0;
alloc.memoryTypeIndex = vulkan_find_memory_type_fallback(&vk->context->memory_properties,
mem_reqs.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | cached,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
}

View File

@ -404,7 +404,8 @@ uint32_t vulkan_find_memory_type(
uint32_t vulkan_find_memory_type_fallback(
const VkPhysicalDeviceMemoryProperties *mem_props,
uint32_t device_reqs, uint32_t host_reqs);
uint32_t device_reqs, uint32_t host_reqs_first,
uint32_t host_reqs_second);
struct vk_texture vulkan_create_texture(vk_t *vk,

View File

@ -1741,6 +1741,10 @@ static bool vulkan_read_viewport(void *data, uint8_t *buffer)
const uint8_t *src;
unsigned x, y;
static struct retro_perf_counter stream_readback = {0};
rarch_perf_init(&stream_readback, "stream_readback");
retro_perf_start(&stream_readback);
buffer += 3 * (vk->vp.height - 1) * vk->vp.width;
vkMapMemory(vk->context->device, staging->memory,
staging->offset, staging->size, 0, (void**)&src);
@ -1750,6 +1754,8 @@ static bool vulkan_read_viewport(void *data, uint8_t *buffer)
scaler_ctx_scale(&vk->readback.scaler, buffer, src);
vkUnmapMemory(vk->context->device, staging->memory);
retro_perf_stop(&stream_readback);
}
else
{