lovr.graphics.present;

It's nice to have an explicit action for presentation.
This commit is contained in:
bjorn 2022-08-04 00:06:54 -07:00
parent 8af3fffe2f
commit acd87a5e5c
6 changed files with 62 additions and 45 deletions

View File

@ -132,6 +132,7 @@ function lovr.run()
pass:reset()
local skip = lovr.mirror(pass)
if not skip then lovr.graphics.submit(pass) end
lovr.graphics.present()
end
end
if lovr.headset then lovr.headset.submit() end

View File

@ -703,6 +703,11 @@ static int l_lovrGraphicsSubmit(lua_State* L) {
return 1;
}
static int l_lovrGraphicsPresent(lua_State* L) {
lovrGraphicsPresent();
return 0;
}
static int l_lovrGraphicsWait(lua_State* L) {
lovrGraphicsWait();
return 0;
@ -1488,6 +1493,7 @@ static int l_lovrGraphicsNewPass(lua_State* L) {
static const luaL_Reg lovrGraphics[] = {
{ "init", l_lovrGraphicsInit },
{ "submit", l_lovrGraphicsSubmit },
{ "present", l_lovrGraphicsPresent },
{ "wait", l_lovrGraphicsWait },
{ "getDevice", l_lovrGraphicsGetDevice },
{ "getFeatures", l_lovrGraphicsGetFeatures },

View File

@ -700,7 +700,8 @@ typedef struct {
bool gpu_init(gpu_config* config);
void gpu_destroy(void);
uint32_t gpu_begin(void);
void gpu_submit(gpu_stream** streams, uint32_t count, bool present);
void gpu_submit(gpu_stream** streams, uint32_t count);
void gpu_present(void);
bool gpu_is_complete(uint32_t tick);
bool gpu_wait_tick(uint32_t tick);
void gpu_wait_idle(void);

View File

@ -2315,7 +2315,7 @@ uint32_t gpu_begin() {
return state.tick[CPU];
}
void gpu_submit(gpu_stream** streams, uint32_t count, bool present) {
void gpu_submit(gpu_stream** streams, uint32_t count) {
gpu_tick* tick = &state.ticks[state.tick[CPU] & TICK_MASK];
VkCommandBuffer commands[COUNTOF(tick->streams)];
@ -2323,35 +2323,43 @@ void gpu_submit(gpu_stream** streams, uint32_t count, bool present) {
commands[i] = streams[i]->commands;
}
VkPipelineStageFlags waitMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo submit = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.waitSemaphoreCount = present,
.waitSemaphoreCount = !!state.surfaceSemaphore,
.pWaitSemaphores = &state.surfaceSemaphore,
.pWaitDstStageMask = &waitMask,
.pWaitDstStageMask = &waitStage,
.commandBufferCount = count,
.pCommandBuffers = commands,
.signalSemaphoreCount = present,
.pSignalSemaphores = &tick->semaphores[1]
.pCommandBuffers = commands
};
VK(vkQueueSubmit(state.queue, 1, &submit, tick->fence), "Queue submit failed") {}
state.surfaceSemaphore = VK_NULL_HANDLE;
}
if (present) {
VkPresentInfoKHR presentInfo = {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &tick->semaphores[1],
.swapchainCount = 1,
.pSwapchains = &state.swapchain,
.pImageIndices = &state.currentSurfaceTexture
};
void gpu_present() {
VkSemaphore semaphore = state.ticks[state.tick[CPU] & TICK_MASK].semaphores[1];
VK(vkQueuePresentKHR(state.queue, &presentInfo), "Queue present failed") {}
state.surfaceSemaphore = VK_NULL_HANDLE;
state.currentSurfaceTexture = ~0u;
}
VkSubmitInfo submit = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.signalSemaphoreCount = 1,
.pSignalSemaphores = &semaphore
};
VK(vkQueueSubmit(state.queue, 1, &submit, VK_NULL_HANDLE), "Queue submit failed") {}
VkPresentInfoKHR present = {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &semaphore,
.swapchainCount = 1,
.pSwapchains = &state.swapchain,
.pImageIndices = &state.currentSurfaceTexture
};
VK(vkQueuePresentKHR(state.queue, &present), "Queue present failed") {}
state.currentSurfaceTexture = ~0u;
}
bool gpu_is_complete(uint32_t tick) {

View File

@ -763,7 +763,6 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
return;
}
bool present = false;
uint32_t total = count + 1;
gpu_stream** streams = tempAlloc(total * sizeof(gpu_stream*));
gpu_barrier* barriers = tempAlloc(count * sizeof(gpu_barrier));
@ -819,26 +818,24 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
Canvas* canvas = &pass->info.canvas;
for (uint32_t j = 0; j < COUNTOF(canvas->textures) && canvas->textures[j]; j++) {
if (canvas->mipmap && canvas->textures[j]->info.mipmaps > 1) {
barriers[i].prev |= GPU_PHASE_COLOR;
if (canvas->mipmap) {
for (uint32_t j = 0; j < COUNTOF(canvas->textures) && canvas->textures[j]; j++) {
if (canvas->textures[j]->info.mipmaps > 1) {
barriers[i].prev |= GPU_PHASE_COLOR;
barriers[i].next |= GPU_PHASE_TRANSFER;
barriers[i].flush |= GPU_CACHE_COLOR_WRITE;
barriers[i].clear |= GPU_CACHE_TRANSFER_READ;
mipmapTexture(pass->stream, canvas->textures[j], 0, ~0u);
}
}
if (canvas->depth.texture && canvas->depth.texture->info.mipmaps > 1) {
barriers[i].prev |= GPU_PHASE_DEPTH_LATE;
barriers[i].next |= GPU_PHASE_TRANSFER;
barriers[i].flush |= GPU_CACHE_COLOR_WRITE;
barriers[i].flush |= GPU_CACHE_DEPTH_WRITE;
barriers[i].clear |= GPU_CACHE_TRANSFER_READ;
mipmapTexture(pass->stream, canvas->textures[j], 0, ~0u);
mipmapTexture(pass->stream, canvas->depth.texture, 0, ~0u);
}
if (canvas->textures[j] == state.window) {
present = true;
}
}
if (canvas->mipmap && canvas->depth.texture && canvas->depth.texture->info.mipmaps > 1) {
barriers[i].prev |= GPU_PHASE_DEPTH_LATE;
barriers[i].next |= GPU_PHASE_TRANSFER;
barriers[i].flush |= GPU_CACHE_DEPTH_WRITE;
barriers[i].clear |= GPU_CACHE_TRANSFER_READ;
mipmapTexture(pass->stream, canvas->depth.texture, 0, ~0u);
}
break;
case PASS_COMPUTE:
@ -958,20 +955,23 @@ void lovrGraphicsSubmit(Pass** passes, uint32_t count) {
gpu_stream_end(streams[i]);
}
gpu_submit(streams, total, present);
gpu_submit(streams, total);
state.stats.pipelineSwitches = 0;
state.stats.bundleSwitches = 0;
if (present) {
state.window->gpu = NULL;
state.window->renderView = NULL;
}
state.stream = NULL;
state.active = false;
}
void lovrGraphicsPresent() {
if (state.window->gpu) {
state.window->gpu = NULL;
state.window->renderView = NULL;
gpu_present();
}
}
void lovrGraphicsWait() {
gpu_wait_idle();
}

View File

@ -110,6 +110,7 @@ bool lovrGraphicsIsFormatSupported(uint32_t format, uint32_t features);
void lovrGraphicsGetShaderCache(void* data, size_t* size);
void lovrGraphicsSubmit(Pass** passes, uint32_t count);
void lovrGraphicsPresent(void);
void lovrGraphicsWait(void);
// Buffer