mirror of
https://github.com/libretro/RetroArch
synced 2025-02-03 17:54:04 +00:00
Vulkan: Fix validation errors with OriginalHistory.
For some reason, OriginalHistory blit happened inside a render pass. Also add more TRANSFER_SRC_BIT caps to images as they might have to be copied to history.
This commit is contained in:
parent
0164ce3725
commit
96818a297c
@ -350,12 +350,15 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
|||||||
case VULKAN_TEXTURE_DYNAMIC:
|
case VULKAN_TEXTURE_DYNAMIC:
|
||||||
retro_assert(!initial && "Dynamic textures must not have initial data.\n");
|
retro_assert(!initial && "Dynamic textures must not have initial data.\n");
|
||||||
info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||||
|
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||||
|
VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||||
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VULKAN_TEXTURE_STREAMED:
|
case VULKAN_TEXTURE_STREAMED:
|
||||||
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT |
|
||||||
|
VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||||
info.tiling = VK_IMAGE_TILING_LINEAR;
|
info.tiling = VK_IMAGE_TILING_LINEAR;
|
||||||
info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
|
info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
|
||||||
break;
|
break;
|
||||||
|
@ -1789,6 +1789,11 @@ static bool vulkan_frame(void *data, const void *frame,
|
|||||||
/* End the render pass. We're done rendering to backbuffer now. */
|
/* End the render pass. We're done rendering to backbuffer now. */
|
||||||
vkCmdEndRenderPass(vk->cmd);
|
vkCmdEndRenderPass(vk->cmd);
|
||||||
|
|
||||||
|
/* End the filter chain frame.
|
||||||
|
* This must happen outside a render pass.
|
||||||
|
*/
|
||||||
|
vulkan_filter_chain_end_frame(vk->filter_chain, vk->cmd);
|
||||||
|
|
||||||
if (vk->readback.pending || vk->readback.streamed)
|
if (vk->readback.pending || vk->readback.streamed)
|
||||||
{
|
{
|
||||||
/* We cannot safely read back from an image which
|
/* We cannot safely read back from an image which
|
||||||
|
@ -559,6 +559,7 @@ struct vulkan_filter_chain
|
|||||||
void build_offscreen_passes(VkCommandBuffer cmd, const VkViewport &vp);
|
void build_offscreen_passes(VkCommandBuffer cmd, const VkViewport &vp);
|
||||||
void build_viewport_pass(VkCommandBuffer cmd,
|
void build_viewport_pass(VkCommandBuffer cmd,
|
||||||
const VkViewport &vp, const float *mvp);
|
const VkViewport &vp, const float *mvp);
|
||||||
|
void end_frame(VkCommandBuffer cmd);
|
||||||
|
|
||||||
void set_frame_count(uint64_t count);
|
void set_frame_count(uint64_t count);
|
||||||
void set_frame_count_period(unsigned pass, unsigned period);
|
void set_frame_count_period(unsigned pass, unsigned period);
|
||||||
@ -1085,6 +1086,18 @@ void vulkan_filter_chain::update_history(DeferredDisposer &disposer, VkCommandBu
|
|||||||
swap(original_history.front(), tmp);
|
swap(original_history.front(), tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vulkan_filter_chain::end_frame(VkCommandBuffer cmd)
|
||||||
|
{
|
||||||
|
// If we need to keep old frames, copy it after fragment is complete.
|
||||||
|
// TODO: We can improve pipelining by figuring out which pass is the last that reads from
|
||||||
|
// the history and dispatch the copy earlier.
|
||||||
|
if (!original_history.empty())
|
||||||
|
{
|
||||||
|
DeferredDisposer disposer(deferred_calls[current_sync_index]);
|
||||||
|
update_history(disposer, cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void vulkan_filter_chain::build_viewport_pass(
|
void vulkan_filter_chain::build_viewport_pass(
|
||||||
VkCommandBuffer cmd, const VkViewport &vp, const float *mvp)
|
VkCommandBuffer cmd, const VkViewport &vp, const float *mvp)
|
||||||
{
|
{
|
||||||
@ -1128,12 +1141,6 @@ void vulkan_filter_chain::build_viewport_pass(
|
|||||||
passes.back()->build_commands(disposer, cmd,
|
passes.back()->build_commands(disposer, cmd,
|
||||||
original, source, vp, mvp);
|
original, source, vp, mvp);
|
||||||
|
|
||||||
// If we need to keep old frames, copy it after fragment is complete.
|
|
||||||
// TODO: We can improve pipelining by figuring out which pass is the last that reads from
|
|
||||||
// the history and dispatch the copy earlier.
|
|
||||||
if (!original_history.empty())
|
|
||||||
update_history(disposer, cmd);
|
|
||||||
|
|
||||||
// For feedback FBOs, swap current and previous.
|
// For feedback FBOs, swap current and previous.
|
||||||
for (auto &pass : passes)
|
for (auto &pass : passes)
|
||||||
pass->end_frame();
|
pass->end_frame();
|
||||||
@ -3188,3 +3195,10 @@ void vulkan_filter_chain_build_viewport_pass(
|
|||||||
chain->build_viewport_pass(cmd, *vp, mvp);
|
chain->build_viewport_pass(cmd, *vp, mvp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vulkan_filter_chain_end_frame(
|
||||||
|
vulkan_filter_chain_t *chain,
|
||||||
|
VkCommandBuffer cmd)
|
||||||
|
{
|
||||||
|
chain->end_frame(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -149,6 +149,8 @@ void vulkan_filter_chain_build_offscreen_passes(vulkan_filter_chain_t *chain,
|
|||||||
VkCommandBuffer cmd, const VkViewport *vp);
|
VkCommandBuffer cmd, const VkViewport *vp);
|
||||||
void vulkan_filter_chain_build_viewport_pass(vulkan_filter_chain_t *chain,
|
void vulkan_filter_chain_build_viewport_pass(vulkan_filter_chain_t *chain,
|
||||||
VkCommandBuffer cmd, const VkViewport *vp, const float *mvp);
|
VkCommandBuffer cmd, const VkViewport *vp, const float *mvp);
|
||||||
|
void vulkan_filter_chain_end_frame(vulkan_filter_chain_t *chain,
|
||||||
|
VkCommandBuffer cmd);
|
||||||
|
|
||||||
vulkan_filter_chain_t *vulkan_filter_chain_create_default(
|
vulkan_filter_chain_t *vulkan_filter_chain_create_default(
|
||||||
const struct vulkan_filter_chain_create_info *info,
|
const struct vulkan_filter_chain_create_info *info,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user