mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-01-28 23:12:14 +00:00
Merge pull request #3220 from Themaister/master
Vulkan: Use manual memory management for cached/incoherent devices.
This commit is contained in:
commit
f816829d99
@ -157,6 +157,7 @@ void vulkan_copy_staging_to_dynamic(vk_t *vk, VkCommandBuffer cmd,
|
||||
retro_assert(dynamic->type == VULKAN_TEXTURE_DYNAMIC);
|
||||
retro_assert(staging->type == VULKAN_TEXTURE_STAGING);
|
||||
|
||||
vulkan_sync_texture_to_gpu(vk, staging);
|
||||
vulkan_transition_texture(vk, staging);
|
||||
|
||||
/* We don't have to sync against previous TRANSFER,
|
||||
@ -240,6 +241,30 @@ static void vulkan_track_dealloc(VkImage image)
|
||||
}
|
||||
#endif
|
||||
|
||||
void vulkan_sync_texture_to_gpu(vk_t *vk, const struct vk_texture *tex)
|
||||
{
|
||||
VkMappedMemoryRange range = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };
|
||||
if (!tex || !tex->need_manual_cache_management || tex->memory == VK_NULL_HANDLE)
|
||||
return;
|
||||
|
||||
range.memory = tex->memory;
|
||||
range.offset = 0;
|
||||
range.size = VK_WHOLE_SIZE;
|
||||
vkFlushMappedMemoryRanges(vk->context->device, 1, &range);
|
||||
}
|
||||
|
||||
void vulkan_sync_texture_to_cpu(vk_t *vk, const struct vk_texture *tex)
|
||||
{
|
||||
VkMappedMemoryRange range = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };
|
||||
if (!tex || !tex->need_manual_cache_management || tex->memory == VK_NULL_HANDLE)
|
||||
return;
|
||||
|
||||
range.memory = tex->memory;
|
||||
range.offset = 0;
|
||||
range.size = VK_WHOLE_SIZE;
|
||||
vkInvalidateMappedMemoryRanges(vk->context->device, 1, &range);
|
||||
}
|
||||
|
||||
struct vk_texture vulkan_create_texture(vk_t *vk,
|
||||
struct vk_texture *old,
|
||||
unsigned width, unsigned height,
|
||||
@ -340,14 +365,18 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Try to find a memory type which is cached, even if it means manual cache management. */
|
||||
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 |
|
||||
VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
|
||||
tex.need_manual_cache_management =
|
||||
(vk->context->memory_properties.memoryTypes[alloc.memoryTypeIndex].propertyFlags &
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -472,6 +501,7 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
||||
for (y = 0; y < tex.height; y++, dst += tex.stride, src += stride)
|
||||
memcpy(dst, src, width * bpp);
|
||||
|
||||
vulkan_sync_texture_to_gpu(vk, &tex);
|
||||
vkUnmapMemory(device, tex.memory);
|
||||
}
|
||||
else if (initial && type == VULKAN_TEXTURE_STATIC)
|
||||
|
@ -170,6 +170,7 @@ struct vk_texture
|
||||
VkImageLayout layout;
|
||||
enum vk_texture_type type;
|
||||
bool default_smooth;
|
||||
bool need_manual_cache_management;
|
||||
};
|
||||
|
||||
struct vk_buffer
|
||||
@ -406,6 +407,9 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
||||
const void *initial, const VkComponentMapping *swizzle,
|
||||
enum vk_texture_type type);
|
||||
|
||||
void vulkan_sync_texture_to_gpu(vk_t *vk, const struct vk_texture *tex);
|
||||
void vulkan_sync_texture_to_cpu(vk_t *vk, const struct vk_texture *tex);
|
||||
|
||||
void vulkan_transition_texture(vk_t *vk, struct vk_texture *texture);
|
||||
|
||||
void vulkan_transfer_image_ownership(VkCommandBuffer cmd,
|
||||
|
@ -1448,22 +1448,6 @@ static void vulkan_readback(vk_t *vk)
|
||||
VK_PIPELINE_STAGE_HOST_BIT);
|
||||
}
|
||||
|
||||
static void vulkan_flush_caches(vk_t *vk)
|
||||
{
|
||||
VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_UNIFORM_READ_BIT;
|
||||
|
||||
vkCmdPipelineBarrier(vk->cmd,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
|
||||
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
false,
|
||||
1, &barrier,
|
||||
0, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static bool vulkan_frame(void *data, const void *frame,
|
||||
unsigned frame_width, unsigned frame_height,
|
||||
uint64_t frame_count,
|
||||
@ -1522,8 +1506,6 @@ static bool vulkan_frame(void *data, const void *frame,
|
||||
|
||||
memset(&vk->tracker, 0, sizeof(vk->tracker));
|
||||
|
||||
vulkan_flush_caches(vk);
|
||||
|
||||
waits_for_semaphores = vk->hw.enable && frame &&
|
||||
!vk->hw.num_cmd && vk->hw.valid_semaphore;
|
||||
|
||||
@ -1591,6 +1573,8 @@ static bool vulkan_frame(void *data, const void *frame,
|
||||
vulkan_copy_staging_to_dynamic(vk, vk->cmd,
|
||||
&chain->texture_optimal, &chain->texture);
|
||||
}
|
||||
else
|
||||
vulkan_sync_texture_to_gpu(vk, &chain->texture);
|
||||
|
||||
vk->last_valid_index = frame_index;
|
||||
}
|
||||
@ -2016,6 +2000,7 @@ static void vulkan_set_texture_frame(void *data,
|
||||
for (y = 0; y < height; y++, dst += texture->stride, src += stride)
|
||||
memcpy(dst, src, stride);
|
||||
|
||||
vulkan_sync_texture_to_gpu(vk, texture);
|
||||
vkUnmapMemory(vk->context->device, texture->memory);
|
||||
|
||||
vk->menu.alpha = alpha;
|
||||
@ -2164,6 +2149,8 @@ static bool vulkan_read_viewport(void *data, uint8_t *buffer)
|
||||
vkMapMemory(vk->context->device, staging->memory,
|
||||
staging->offset, staging->size, 0, (void**)&src);
|
||||
|
||||
vulkan_sync_texture_to_cpu(vk, staging);
|
||||
|
||||
vk->readback.scaler.in_stride = staging->stride;
|
||||
vk->readback.scaler.out_stride = -(int)vk->vp.width * 3;
|
||||
scaler_ctx_scale(&vk->readback.scaler, buffer, src);
|
||||
@ -2187,6 +2174,8 @@ static bool vulkan_read_viewport(void *data, uint8_t *buffer)
|
||||
vulkan_map_persistent_texture(
|
||||
vk->context->device, staging);
|
||||
|
||||
vulkan_sync_texture_to_cpu(vk, staging);
|
||||
|
||||
{
|
||||
unsigned x, y;
|
||||
const uint8_t *src = (const uint8_t*)staging->mapped;
|
||||
|
Loading…
x
Reference in New Issue
Block a user