mirror of https://github.com/bjornbytes/lovr.git
Fix window resize;
This commit is contained in:
parent
3775ed1be6
commit
9783140725
10
etc/boot.lua
10
etc/boot.lua
|
@ -135,7 +135,7 @@ function lovr.run()
|
|||
if lovr.system.isWindowOpen() then
|
||||
if lovr.mirror then
|
||||
local pass = lovr.graphics.getWindowPass()
|
||||
local skip = lovr.mirror(pass)
|
||||
local skip = not pass or lovr.mirror(pass)
|
||||
if not skip then lovr.graphics.submit(pass) end
|
||||
end
|
||||
lovr.graphics.present()
|
||||
|
@ -213,9 +213,11 @@ function lovr.errhand(message)
|
|||
|
||||
if lovr.system.isWindowOpen() then
|
||||
local pass = lovr.graphics.getWindowPass()
|
||||
render(pass)
|
||||
lovr.graphics.submit(pass)
|
||||
lovr.graphics.present()
|
||||
if pass then
|
||||
render(pass)
|
||||
lovr.graphics.submit(pass)
|
||||
lovr.graphics.present()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -165,18 +165,24 @@ static int l_lovrSystemIsWindowOpen(lua_State* L) {
|
|||
}
|
||||
|
||||
static int l_lovrSystemGetWindowWidth(lua_State* L) {
|
||||
lua_pushnumber(L, lovrSystemGetWindowWidth());
|
||||
uint32_t width, height;
|
||||
lovrSystemGetWindowSize(&width, &height);
|
||||
lua_pushnumber(L, width);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrSystemGetWindowHeight(lua_State* L) {
|
||||
lua_pushnumber(L, lovrSystemGetWindowHeight());
|
||||
uint32_t width, height;
|
||||
lovrSystemGetWindowSize(&width, &height);
|
||||
lua_pushnumber(L, height);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrSystemGetWindowDimensions(lua_State* L) {
|
||||
lua_pushnumber(L, lovrSystemGetWindowWidth());
|
||||
lua_pushnumber(L, lovrSystemGetWindowHeight());
|
||||
uint32_t width, height;
|
||||
lovrSystemGetWindowSize(&width, &height);
|
||||
lua_pushnumber(L, width);
|
||||
lua_pushnumber(L, height);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,7 @@ bool gpu_texture_init(gpu_texture* texture, gpu_texture_info* info);
|
|||
bool gpu_texture_init_view(gpu_texture* texture, gpu_texture_view_info* info);
|
||||
void gpu_texture_destroy(gpu_texture* texture);
|
||||
gpu_texture* gpu_surface_acquire(void);
|
||||
void gpu_surface_resize(uint32_t width, uint32_t height);
|
||||
void gpu_xr_acquire(gpu_stream* stream, gpu_texture* texture);
|
||||
void gpu_xr_release(gpu_stream* stream, gpu_texture* texture);
|
||||
|
||||
|
|
|
@ -169,11 +169,13 @@ static struct {
|
|||
VkQueue queue;
|
||||
uint32_t queueFamilyIndex;
|
||||
VkSurfaceKHR surface;
|
||||
VkSurfaceCapabilitiesKHR surfaceCapabilities;
|
||||
VkSurfaceFormatKHR surfaceFormat;
|
||||
bool swapchainValid;
|
||||
VkSwapchainKHR swapchain;
|
||||
VkFormat surfaceFormat;
|
||||
VkSemaphore surfaceSemaphore;
|
||||
uint32_t currentSurfaceTexture;
|
||||
gpu_texture surfaceTextures[8];
|
||||
VkSemaphore swapchainSemaphore;
|
||||
uint32_t currentSwapchainTexture;
|
||||
gpu_texture swapchainTextures[8];
|
||||
VkPipelineCache pipelineCache;
|
||||
VkDebugUtilsMessengerEXT messenger;
|
||||
gpu_cache_entry renderpasses[16][4];
|
||||
|
@ -208,6 +210,7 @@ static gpu_memory* gpu_allocate(gpu_memory_type type, VkMemoryRequirements info,
|
|||
static void gpu_release(gpu_memory* memory);
|
||||
static void condemn(void* handle, VkObjectType type);
|
||||
static void expunge(void);
|
||||
static void createSwapchain(uint32_t width, uint32_t height);
|
||||
static VkRenderPass getCachedRenderPass(gpu_pass_info* pass, bool exact);
|
||||
static VkFramebuffer getCachedFramebuffer(VkRenderPass pass, VkImageView images[9], uint32_t imageCount, uint32_t size[2]);
|
||||
static VkImageLayout getNaturalLayout(uint32_t usage, VkImageAspectFlags aspect);
|
||||
|
@ -738,11 +741,28 @@ void gpu_texture_destroy(gpu_texture* texture) {
|
|||
gpu_release(state.memory + texture->memory);
|
||||
}
|
||||
|
||||
gpu_texture* gpu_surface_acquire(void) {
|
||||
gpu_texture* gpu_surface_acquire() {
|
||||
if (!state.swapchainValid) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gpu_tick* tick = &state.ticks[state.tick[CPU] & TICK_MASK];
|
||||
state.surfaceSemaphore = tick->semaphores[0];
|
||||
VK(vkAcquireNextImageKHR(state.device, state.swapchain, UINT64_MAX, state.surfaceSemaphore, VK_NULL_HANDLE, &state.currentSurfaceTexture), "Surface image acquisition failed") return NULL;
|
||||
return &state.surfaceTextures[state.currentSurfaceTexture];
|
||||
VkResult result = vkAcquireNextImageKHR(state.device, state.swapchain, UINT64_MAX, tick->semaphores[0], VK_NULL_HANDLE, &state.currentSwapchainTexture);
|
||||
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
state.currentSwapchainTexture = ~0u;
|
||||
state.swapchainValid = false;
|
||||
return NULL;
|
||||
} else {
|
||||
vcheck(result, "Failed to acquire swapchain");
|
||||
}
|
||||
|
||||
state.swapchainSemaphore = tick->semaphores[0];
|
||||
return &state.swapchainTextures[state.currentSwapchainTexture];
|
||||
}
|
||||
|
||||
void gpu_surface_resize(uint32_t width, uint32_t height) {
|
||||
createSwapchain(width, height);
|
||||
}
|
||||
|
||||
// The barriers here are a bit lazy (oversynchronized) and can be improved
|
||||
|
@ -2219,68 +2239,26 @@ bool gpu_init(gpu_config* config) {
|
|||
}
|
||||
}
|
||||
|
||||
// Swapchain
|
||||
if (state.surface) {
|
||||
VkSurfaceCapabilitiesKHR surfaceCapabilities;
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(state.adapter, state.surface, &surfaceCapabilities);
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(state.adapter, state.surface, &state.surfaceCapabilities);
|
||||
|
||||
VkSurfaceFormatKHR formats[16];
|
||||
VkSurfaceFormatKHR formats[32];
|
||||
uint32_t formatCount = COUNTOF(formats);
|
||||
VkSurfaceFormatKHR surfaceFormat = { .format = VK_FORMAT_UNDEFINED };
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(state.adapter, state.surface, &formatCount, formats);
|
||||
|
||||
for (uint32_t i = 0; i < formatCount; i++) {
|
||||
if (formats[i].format == VK_FORMAT_R8G8B8A8_SRGB || formats[i].format == VK_FORMAT_B8G8R8A8_SRGB) {
|
||||
surfaceFormat = formats[i];
|
||||
state.surfaceFormat = formats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VK(surfaceFormat.format == VK_FORMAT_UNDEFINED ? VK_ERROR_FORMAT_NOT_SUPPORTED : VK_SUCCESS, "No supported surface formats") return gpu_destroy(), false;
|
||||
state.surfaceFormat = surfaceFormat.format;
|
||||
VK(state.surfaceFormat.format == VK_FORMAT_UNDEFINED ? VK_ERROR_FORMAT_NOT_SUPPORTED : VK_SUCCESS, "No supported surface formats") return gpu_destroy(), false;
|
||||
|
||||
VkSwapchainCreateInfoKHR swapchainInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
|
||||
.surface = state.surface,
|
||||
.minImageCount = surfaceCapabilities.minImageCount,
|
||||
.imageFormat = surfaceFormat.format,
|
||||
.imageColorSpace = surfaceFormat.colorSpace,
|
||||
.imageExtent = surfaceCapabilities.currentExtent,
|
||||
.imageArrayLayers = 1,
|
||||
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
|
||||
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
|
||||
.presentMode = state.config.vk.vsync ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR,
|
||||
.clipped = VK_TRUE
|
||||
};
|
||||
uint32_t width = state.surfaceCapabilities.currentExtent.width;
|
||||
uint32_t height = state.surfaceCapabilities.currentExtent.height;
|
||||
|
||||
VK(vkCreateSwapchainKHR(state.device, &swapchainInfo, NULL, &state.swapchain), "Swapchain creation failed") return gpu_destroy(), false;
|
||||
|
||||
uint32_t imageCount;
|
||||
VkImage images[COUNTOF(state.surfaceTextures)];
|
||||
VK(vkGetSwapchainImagesKHR(state.device, state.swapchain, &imageCount, NULL), "Failed to get swapchain images") return gpu_destroy(), false;
|
||||
VK(imageCount > COUNTOF(images) ? VK_ERROR_TOO_MANY_OBJECTS : VK_SUCCESS, "Failed to get swapchain images") return gpu_destroy(), false;
|
||||
VK(vkGetSwapchainImagesKHR(state.device, state.swapchain, &imageCount, images), "Failed to get swapchain images") return gpu_destroy(), false;
|
||||
|
||||
for (uint32_t i = 0; i < imageCount; i++) {
|
||||
gpu_texture* texture = &state.surfaceTextures[i];
|
||||
|
||||
texture->handle = images[i];
|
||||
texture->aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
texture->layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
texture->samples = 1;
|
||||
texture->memory = ~0u;
|
||||
texture->layers = 1;
|
||||
texture->format = GPU_FORMAT_SURFACE;
|
||||
texture->srgb = true;
|
||||
|
||||
gpu_texture_view_info view = {
|
||||
.source = texture,
|
||||
.type = GPU_TEXTURE_2D
|
||||
};
|
||||
|
||||
CHECK(gpu_texture_init_view(texture, &view), "Swapchain texture view creation failed") return gpu_destroy(), false;
|
||||
}
|
||||
createSwapchain(width, height);
|
||||
}
|
||||
|
||||
// Ticks
|
||||
|
@ -2338,7 +2316,7 @@ bool gpu_init(gpu_config* config) {
|
|||
VK(vkCreatePipelineCache(state.device, &cacheInfo, NULL, &state.pipelineCache), "Pipeline cache creation failed") return gpu_destroy(), false;
|
||||
|
||||
state.tick[CPU] = COUNTOF(state.ticks) - 1;
|
||||
state.currentSurfaceTexture = ~0u;
|
||||
state.currentSwapchainTexture = ~0u;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2371,8 +2349,8 @@ void gpu_destroy(void) {
|
|||
for (uint32_t i = 0; i < COUNTOF(state.memory); i++) {
|
||||
if (state.memory[i].handle) vkFreeMemory(state.device, state.memory[i].handle, NULL);
|
||||
}
|
||||
for (uint32_t i = 0; i < COUNTOF(state.surfaceTextures); i++) {
|
||||
if (state.surfaceTextures[i].view) vkDestroyImageView(state.device, state.surfaceTextures[i].view, NULL);
|
||||
for (uint32_t i = 0; i < COUNTOF(state.swapchainTextures); i++) {
|
||||
if (state.swapchainTextures[i].view) vkDestroyImageView(state.device, state.swapchainTextures[i].view, NULL);
|
||||
}
|
||||
if (state.swapchain) vkDestroySwapchainKHR(state.device, state.swapchain, NULL);
|
||||
if (state.device) vkDestroyDevice(state.device, NULL);
|
||||
|
@ -2411,15 +2389,15 @@ void gpu_submit(gpu_stream** streams, uint32_t count) {
|
|||
|
||||
VkSubmitInfo submit = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.waitSemaphoreCount = !!state.surfaceSemaphore,
|
||||
.pWaitSemaphores = &state.surfaceSemaphore,
|
||||
.waitSemaphoreCount = !!state.swapchainSemaphore,
|
||||
.pWaitSemaphores = &state.swapchainSemaphore,
|
||||
.pWaitDstStageMask = &waitStage,
|
||||
.commandBufferCount = count,
|
||||
.pCommandBuffers = commands
|
||||
};
|
||||
|
||||
VK(vkQueueSubmit(state.queue, 1, &submit, tick->fence), "Queue submit failed") {}
|
||||
state.surfaceSemaphore = VK_NULL_HANDLE;
|
||||
state.swapchainSemaphore = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
void gpu_present() {
|
||||
|
@ -2439,11 +2417,18 @@ void gpu_present() {
|
|||
.pWaitSemaphores = &semaphore,
|
||||
.swapchainCount = 1,
|
||||
.pSwapchains = &state.swapchain,
|
||||
.pImageIndices = &state.currentSurfaceTexture
|
||||
.pImageIndices = &state.currentSwapchainTexture
|
||||
};
|
||||
|
||||
VK(vkQueuePresentKHR(state.queue, &present), "Queue present failed") {}
|
||||
state.currentSurfaceTexture = ~0u;
|
||||
VkResult result = vkQueuePresentKHR(state.queue, &present);
|
||||
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
state.swapchainValid = false;
|
||||
} else {
|
||||
vcheck(result, "Queue present failed");
|
||||
}
|
||||
|
||||
state.currentSwapchainTexture = ~0u;
|
||||
}
|
||||
|
||||
bool gpu_is_complete(uint32_t tick) {
|
||||
|
@ -2601,6 +2586,76 @@ static void expunge() {
|
|||
}
|
||||
}
|
||||
|
||||
static void createSwapchain(uint32_t width, uint32_t height) {
|
||||
if (width == 0 || height == 0) {
|
||||
state.swapchainValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
VkSwapchainKHR oldSwapchain = state.swapchain;
|
||||
|
||||
if (oldSwapchain) {
|
||||
vkDeviceWaitIdle(state.device);
|
||||
}
|
||||
|
||||
VkSwapchainCreateInfoKHR swapchainInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
|
||||
.surface = state.surface,
|
||||
.minImageCount = state.surfaceCapabilities.minImageCount,
|
||||
.imageFormat = state.surfaceFormat.format,
|
||||
.imageColorSpace = state.surfaceFormat.colorSpace,
|
||||
.imageExtent = { width, height },
|
||||
.imageArrayLayers = 1,
|
||||
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
|
||||
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
|
||||
.presentMode = state.config.vk.vsync ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR,
|
||||
.clipped = VK_TRUE,
|
||||
.oldSwapchain = oldSwapchain
|
||||
};
|
||||
|
||||
VK(vkCreateSwapchainKHR(state.device, &swapchainInfo, NULL, &state.swapchain), "Swapchain creation failed") return;
|
||||
|
||||
if (oldSwapchain) {
|
||||
for (uint32_t i = 0; i < COUNTOF(state.swapchainTextures); i++) {
|
||||
if (state.swapchainTextures[i].view) {
|
||||
vkDestroyImageView(state.device, state.swapchainTextures[i].view, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
memset(state.swapchainTextures, 0, sizeof(state.swapchainTextures));
|
||||
vkDestroySwapchainKHR(state.device, oldSwapchain, NULL);
|
||||
}
|
||||
|
||||
uint32_t imageCount;
|
||||
VkImage images[COUNTOF(state.swapchainTextures)];
|
||||
VK(vkGetSwapchainImagesKHR(state.device, state.swapchain, &imageCount, NULL), "Failed to get swapchain images") return;
|
||||
VK(imageCount > COUNTOF(images) ? VK_ERROR_TOO_MANY_OBJECTS : VK_SUCCESS, "Failed to get swapchain images") return;
|
||||
VK(vkGetSwapchainImagesKHR(state.device, state.swapchain, &imageCount, images), "Failed to get swapchain images") return;
|
||||
|
||||
for (uint32_t i = 0; i < imageCount; i++) {
|
||||
gpu_texture* texture = &state.swapchainTextures[i];
|
||||
|
||||
texture->handle = images[i];
|
||||
texture->aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
texture->layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
texture->samples = 1;
|
||||
texture->memory = ~0u;
|
||||
texture->layers = 1;
|
||||
texture->format = GPU_FORMAT_SURFACE;
|
||||
texture->srgb = true;
|
||||
|
||||
gpu_texture_view_info view = {
|
||||
.source = texture,
|
||||
.type = GPU_TEXTURE_2D
|
||||
};
|
||||
|
||||
CHECK(gpu_texture_init_view(texture, &view), "Swapchain texture view creation failed") return;
|
||||
}
|
||||
|
||||
state.swapchainValid = true;
|
||||
}
|
||||
|
||||
// Ugliness until we can use dynamic rendering
|
||||
static VkRenderPass getCachedRenderPass(gpu_pass_info* pass, bool exact) {
|
||||
bool depth = pass->depth.layout != VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
@ -2684,7 +2739,7 @@ static VkRenderPass getCachedRenderPass(gpu_pass_info* pass, bool exact) {
|
|||
for (uint32_t i = 0; i < count; i++) {
|
||||
references[i].attachment = i;
|
||||
references[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
bool surface = pass->color[i].format == state.surfaceFormat;
|
||||
bool surface = pass->color[i].format == state.surfaceFormat.format; // FIXME
|
||||
bool discard = surface || pass->color[i].load != GPU_LOAD_OP_KEEP;
|
||||
attachments[i] = (VkAttachmentDescription) {
|
||||
.format = pass->color[i].format,
|
||||
|
@ -2701,7 +2756,7 @@ static VkRenderPass getCachedRenderPass(gpu_pass_info* pass, bool exact) {
|
|||
uint32_t index = count + i;
|
||||
references[index].attachment = index;
|
||||
references[index].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
bool surface = pass->color[i].format == state.surfaceFormat;
|
||||
bool surface = pass->color[i].format == state.surfaceFormat.format; // FIXME
|
||||
attachments[index] = (VkAttachmentDescription) {
|
||||
.format = pass->color[i].format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
|
@ -2879,7 +2934,7 @@ static VkFormat convertFormat(gpu_texture_format format, int colorspace) {
|
|||
};
|
||||
|
||||
if (format == GPU_FORMAT_SURFACE) {
|
||||
return state.surfaceFormat;
|
||||
return state.surfaceFormat.format;
|
||||
}
|
||||
|
||||
return formats[format][colorspace];
|
||||
|
|
|
@ -128,7 +128,7 @@ typedef enum {
|
|||
typedef void fn_gl_proc(void);
|
||||
typedef void fn_quit(void);
|
||||
typedef void fn_focus(bool focused);
|
||||
typedef void fn_resize(int width, int height);
|
||||
typedef void fn_resize(uint32_t width, uint32_t height);
|
||||
typedef void fn_key(os_button_action action, os_key key, uint32_t scancode, bool repeat);
|
||||
typedef void fn_text(uint32_t codepoint);
|
||||
typedef void fn_permission(os_permission permission, bool granted);
|
||||
|
@ -157,8 +157,8 @@ void os_on_permission(fn_permission* callback);
|
|||
|
||||
bool os_window_open(const os_window_config* config);
|
||||
bool os_window_is_open(void);
|
||||
void os_window_get_size(int* width, int* height);
|
||||
void os_window_get_fbsize(int* width, int* height);
|
||||
void os_window_get_size(uint32_t* width, uint32_t* height);
|
||||
void os_window_get_fbsize(uint32_t* width, uint32_t* height);
|
||||
|
||||
size_t os_get_home_directory(char* buffer, size_t size);
|
||||
size_t os_get_data_directory(char* buffer, size_t size);
|
||||
|
|
|
@ -319,12 +319,12 @@ bool os_window_is_open() {
|
|||
return false;
|
||||
}
|
||||
|
||||
void os_window_get_size(int* width, int* height) {
|
||||
void os_window_get_size(uint32_t* width, uint32_t* height) {
|
||||
if (width) *width = 0;
|
||||
if (height) *height = 0;
|
||||
}
|
||||
|
||||
void os_window_get_fbsize(int* width, int* height) {
|
||||
void os_window_get_fbsize(uint32_t* width, uint32_t* height) {
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
}
|
||||
|
|
|
@ -248,21 +248,27 @@ bool os_window_is_open() {
|
|||
return glfwState.window;
|
||||
}
|
||||
|
||||
void os_window_get_size(int* width, int* height) {
|
||||
void os_window_get_size(uint32_t* width, uint32_t* height) {
|
||||
if (glfwState.window) {
|
||||
glfwGetWindowSize(glfwState.window, width, height);
|
||||
int w, h;
|
||||
glfwGetWindowSize(glfwState.window, &w, &h);
|
||||
*width = w;
|
||||
*height = h;
|
||||
} else {
|
||||
if (*width) *width = 0;
|
||||
if (*height) *height = 0;
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void os_window_get_fbsize(int* width, int* height) {
|
||||
void os_window_get_fbsize(uint32_t* width, uint32_t* height) {
|
||||
if (glfwState.window) {
|
||||
glfwGetFramebufferSize(glfwState.window, width, height);
|
||||
int w, h;
|
||||
glfwGetFramebufferSize(glfwState.window, &w, &h);
|
||||
*width = w;
|
||||
*height = h;
|
||||
} else {
|
||||
if (*width) *width = 0;
|
||||
if (*height) *height = 0;
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,10 +19,10 @@ static struct {
|
|||
os_mouse_mode mouseMode;
|
||||
long mouseX;
|
||||
long mouseY;
|
||||
int width;
|
||||
int height;
|
||||
int framebufferWidth;
|
||||
int framebufferHeight;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t framebufferWidth;
|
||||
uint32_t framebufferHeight;
|
||||
} state;
|
||||
|
||||
static const char* onBeforeUnload(int type, const void* unused, void* userdata) {
|
||||
|
@ -45,7 +45,7 @@ static EM_BOOL onResize(int type, const EmscriptenUiEvent* data, void* userdata)
|
|||
|
||||
int newWidth, newHeight;
|
||||
emscripten_get_canvas_element_size(CANVAS, &newWidth, &newHeight);
|
||||
if (state.width != newWidth || state.height != newHeight) {
|
||||
if (state.width != (uint32_t) newWidth || state.height != (uint32_t) newHeight) {
|
||||
state.width = newWidth;
|
||||
state.height = newHeight;
|
||||
if (state.onWindowResize) {
|
||||
|
@ -298,12 +298,12 @@ bool os_window_is_open() {
|
|||
return state.context > 0;
|
||||
}
|
||||
|
||||
void os_window_get_size(int* width, int* height) {
|
||||
void os_window_get_size(uint32_t* width, uint32_t* height) {
|
||||
*width = state.width;
|
||||
*height = state.height;
|
||||
}
|
||||
|
||||
void os_window_get_fbsize(int* width, int* height) {
|
||||
void os_window_get_fbsize(uint32_t* width, uint32_t* height) {
|
||||
*width = state.framebufferWidth;
|
||||
*height = state.framebufferHeight;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "data/image.h"
|
||||
#include "data/modelData.h"
|
||||
#include "data/rasterizer.h"
|
||||
#include "event/event.h"
|
||||
#include "headset/headset.h"
|
||||
#include "math/math.h"
|
||||
#include "core/gpu.h"
|
||||
|
@ -426,6 +427,7 @@ static void trackTexture(Pass* pass, Texture* texture, gpu_phase phase, gpu_cach
|
|||
static void trackMaterial(Pass* pass, Material* material, gpu_phase phase, gpu_cache cache);
|
||||
static void updateModelTransforms(Model* model, uint32_t nodeIndex, float* parent);
|
||||
static void checkShaderFeatures(uint32_t* features, uint32_t count);
|
||||
static void onResize(uint32_t width, uint32_t height);
|
||||
static void onMessage(void* context, const char* message, bool severe);
|
||||
|
||||
// Entry
|
||||
|
@ -450,6 +452,7 @@ bool lovrGraphicsInit(GraphicsConfig* config) {
|
|||
gpu.vk.cacheSize = config->cacheSize;
|
||||
|
||||
if (os_window_is_open()) {
|
||||
os_on_resize(onResize);
|
||||
gpu.vk.getInstanceExtensions = os_vk_get_instance_extensions;
|
||||
gpu.vk.createSurface = os_vk_create_surface;
|
||||
gpu.vk.surface = true;
|
||||
|
@ -632,17 +635,12 @@ bool lovrGraphicsInit(GraphicsConfig* config) {
|
|||
state.window = malloc(sizeof(Texture));
|
||||
lovrAssert(state.window, "Out of memory");
|
||||
|
||||
int width, height;
|
||||
os_window_get_fbsize(&width, &height);
|
||||
|
||||
state.window->ref = 1;
|
||||
state.window->gpu = NULL;
|
||||
state.window->renderView = NULL;
|
||||
state.window->info = (TextureInfo) {
|
||||
.type = TEXTURE_2D,
|
||||
.format = GPU_FORMAT_SURFACE,
|
||||
.width = width,
|
||||
.height = height,
|
||||
.layers = 1,
|
||||
.mipmaps = 1,
|
||||
.samples = 1,
|
||||
|
@ -650,6 +648,8 @@ bool lovrGraphicsInit(GraphicsConfig* config) {
|
|||
.srgb = true
|
||||
};
|
||||
|
||||
os_window_get_size(&state.window->info.width, &state.window->info.height);
|
||||
|
||||
state.depthFormat = config->stencil ? FORMAT_D32FS8 : FORMAT_D32F;
|
||||
|
||||
if (config->stencil && !lovrGraphicsIsFormatSupported(state.depthFormat, TEXTURE_FEATURE_RENDER)) {
|
||||
|
@ -1104,7 +1104,7 @@ Buffer* lovrGraphicsGetBuffer(BufferInfo* info, void** data) {
|
|||
arr_push(&state.scratchBufferHandles, handles);
|
||||
}
|
||||
|
||||
uint32_t index = state.scratchBufferIndex++;
|
||||
size_t index = state.scratchBufferIndex++;
|
||||
Buffer* buffer = &state.scratchBuffers.data[index / BUFFERS_PER_CHUNK][index % BUFFERS_PER_CHUNK];
|
||||
|
||||
buffer->ref = 1;
|
||||
|
@ -1191,8 +1191,14 @@ void lovrBufferClear(Buffer* buffer, uint32_t offset, uint32_t size) {
|
|||
Texture* lovrGraphicsGetWindowTexture() {
|
||||
if (!state.window->gpu) {
|
||||
beginFrame();
|
||||
|
||||
state.window->gpu = gpu_surface_acquire();
|
||||
state.window->renderView = state.window->gpu;
|
||||
|
||||
// Window texture may be unavailable during a resize
|
||||
if (!state.window->gpu) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return state.window;
|
||||
|
@ -3209,10 +3215,17 @@ static void lovrPassCheckValid(Pass* pass) {
|
|||
|
||||
Pass* lovrGraphicsGetWindowPass() {
|
||||
if (!state.windowPass && state.window) {
|
||||
Texture* window = lovrGraphicsGetWindowTexture();
|
||||
|
||||
// The window texture (and therefore the window pass) may become unavailable during a resize
|
||||
if (!window) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PassInfo info = {
|
||||
.type = PASS_RENDER,
|
||||
.canvas.count = 1,
|
||||
.canvas.textures[0] = state.window,
|
||||
.canvas.textures[0] = window,
|
||||
.canvas.depth.format = state.depthFormat,
|
||||
.canvas.samples = state.config.antialias ? 4 : 1,
|
||||
.label = "Window"
|
||||
|
@ -3333,10 +3346,6 @@ Pass* lovrGraphicsGetPass(PassInfo* info) {
|
|||
};
|
||||
|
||||
for (uint32_t i = 0; i < canvas->count; i++) {
|
||||
if (canvas->textures[i] == state.window) {
|
||||
canvas->textures[i] = lovrGraphicsGetWindowTexture(); // Make sure swapchain handle is updated
|
||||
}
|
||||
|
||||
if (t->samples == 1 && canvas->samples > 1) {
|
||||
scratchTextureInfo.format = canvas->textures[i]->info.format;
|
||||
scratchTextureInfo.srgb = canvas->textures[i]->info.srgb;
|
||||
|
@ -5891,6 +5900,19 @@ static void checkShaderFeatures(uint32_t* features, uint32_t count) {
|
|||
}
|
||||
}
|
||||
|
||||
static void onResize(uint32_t width, uint32_t height) {
|
||||
state.window->info.width = width;
|
||||
state.window->info.height = height;
|
||||
|
||||
gpu_surface_resize(width, height);
|
||||
|
||||
lovrEventPush((Event) {
|
||||
.type = EVENT_RESIZE,
|
||||
.data.resize.width = width,
|
||||
.data.resize.height = height
|
||||
});
|
||||
}
|
||||
|
||||
static void onMessage(void* context, const char* message, bool severe) {
|
||||
if (severe) {
|
||||
lovrThrow("GPU error: %s", message);
|
||||
|
|
|
@ -84,10 +84,7 @@ static double desktop_getDeltaTime(void) {
|
|||
}
|
||||
|
||||
static void desktop_getDisplayDimensions(uint32_t* width, uint32_t* height) {
|
||||
int w, h;
|
||||
os_window_get_fbsize(&w, &h);
|
||||
*width = (uint32_t) w;
|
||||
*height = (uint32_t) h;
|
||||
os_window_get_fbsize(width, height);
|
||||
}
|
||||
|
||||
static uint32_t desktop_getViewCount(void) {
|
||||
|
@ -244,10 +241,10 @@ static double desktop_update(void) {
|
|||
float turnspeed = 3.f * (float) dt;
|
||||
float damping = MAX(1.f - 20.f * (float) dt, 0);
|
||||
|
||||
int width, height;
|
||||
double mx, my;
|
||||
os_window_get_fbsize(&width, &height);
|
||||
uint32_t width, height;
|
||||
os_get_mouse_position(&mx, &my);
|
||||
os_window_get_fbsize(&width, &height);
|
||||
|
||||
double aspect = (width > 0 && height > 0) ? ((double) width / height) : 1.;
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
static struct {
|
||||
bool initialized;
|
||||
int windowWidth;
|
||||
int windowHeight;
|
||||
bool pressedKeys[KEY_COUNT];
|
||||
} state;
|
||||
|
||||
|
@ -45,11 +43,6 @@ static void onQuit(void) {
|
|||
});
|
||||
}
|
||||
|
||||
static void onResize(int width, int height) {
|
||||
state.windowWidth = width;
|
||||
state.windowHeight = height;
|
||||
}
|
||||
|
||||
bool lovrSystemInit() {
|
||||
if (state.initialized) return false;
|
||||
os_on_key(onKey);
|
||||
|
@ -85,25 +78,19 @@ void lovrSystemRequestPermission(Permission permission) {
|
|||
|
||||
void lovrSystemOpenWindow(os_window_config* window) {
|
||||
lovrAssert(os_window_open(window), "Could not open window");
|
||||
os_on_resize(onResize);
|
||||
os_on_quit(onQuit);
|
||||
os_window_get_fbsize(&state.windowWidth, &state.windowHeight);
|
||||
}
|
||||
|
||||
bool lovrSystemIsWindowOpen() {
|
||||
return os_window_is_open();
|
||||
}
|
||||
|
||||
uint32_t lovrSystemGetWindowWidth() {
|
||||
return state.windowWidth;
|
||||
}
|
||||
|
||||
uint32_t lovrSystemGetWindowHeight() {
|
||||
return state.windowHeight;
|
||||
void lovrSystemGetWindowSize(uint32_t* width, uint32_t* height) {
|
||||
os_window_get_fbsize(width, height);
|
||||
}
|
||||
|
||||
float lovrSystemGetWindowDensity() {
|
||||
int width, height, fbwidth, fbheight;
|
||||
uint32_t width, height, fbwidth, fbheight;
|
||||
os_window_get_size(&width, &height);
|
||||
os_window_get_fbsize(&fbwidth, &fbheight);
|
||||
return (width == 0 || fbwidth == 0) ? 0.f : (float) fbwidth / width;
|
||||
|
|
|
@ -16,7 +16,6 @@ uint32_t lovrSystemGetCoreCount(void);
|
|||
void lovrSystemRequestPermission(Permission permission);
|
||||
void lovrSystemOpenWindow(struct os_window_config* config);
|
||||
bool lovrSystemIsWindowOpen(void);
|
||||
uint32_t lovrSystemGetWindowWidth(void);
|
||||
uint32_t lovrSystemGetWindowHeight(void);
|
||||
void lovrSystemGetWindowSize(uint32_t* width, uint32_t* height);
|
||||
float lovrSystemGetWindowDensity(void);
|
||||
bool lovrSystemIsKeyDown(int keycode);
|
||||
|
|
Loading…
Reference in New Issue