mirror of https://github.com/bjornbytes/lovr.git
lovr.graphics.present;
It's nice to have an explicit action for presentation.
This commit is contained in:
parent
8af3fffe2f
commit
acd87a5e5c
|
@ -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
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue