move swapchain to framectl; make validation errors crash process early
This commit is contained in:
parent
4d6739da0a
commit
d4c463c507
|
@ -4,6 +4,7 @@
|
|||
#include "vk_core.h"
|
||||
#include "vk_common.h"
|
||||
#include "vk_textures.h"
|
||||
#include "vk_framectl.h"
|
||||
|
||||
#include "com_strings.h"
|
||||
#include "eiface.h"
|
||||
|
@ -71,6 +72,7 @@ void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, f
|
|||
|
||||
g2d.batch[g2d.current_batch].texture = texnum;
|
||||
g2d.batch[g2d.current_batch].vertex_offset = g2d.num_pics;
|
||||
g2d.batch[g2d.current_batch].vertex_count = 0;
|
||||
}
|
||||
|
||||
if (g2d.num_pics + 6 > g2d.max_pics)
|
||||
|
@ -83,8 +85,8 @@ void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, f
|
|||
{
|
||||
vertex_2d_t *p = ((vertex_2d_t*)(g2d.pics_buffer.mapped)) + g2d.num_pics;
|
||||
|
||||
const float vw = vk_core.swapchain.create_info.imageExtent.width;
|
||||
const float vh = vk_core.swapchain.create_info.imageExtent.height;
|
||||
const float vw = vk_frame.create_info.imageExtent.width;
|
||||
const float vh = vk_frame.create_info.imageExtent.height;
|
||||
const float x1 = (x / vw)*2.f - 1.f;
|
||||
const float y1 = (y / vh)*2.f - 1.f;
|
||||
const float x2 = ((x + w) / vw)*2.f - 1.f;
|
||||
|
@ -142,13 +144,13 @@ static VkPipeline createPipeline( void )
|
|||
|
||||
VkViewport viewport = {
|
||||
.x = 0, .y = 0,
|
||||
.width = (float)vk_core.swapchain.create_info.imageExtent.width,
|
||||
.height = (float)vk_core.swapchain.create_info.imageExtent.height,
|
||||
.width = (float)vk_frame.create_info.imageExtent.width,
|
||||
.height = (float)vk_frame.create_info.imageExtent.height,
|
||||
.minDepth = 0.f, .maxDepth = 1.f,
|
||||
};
|
||||
VkRect2D scissor = {
|
||||
.offset = {0},
|
||||
.extent = vk_core.swapchain.create_info.imageExtent,
|
||||
.extent = vk_frame.create_info.imageExtent,
|
||||
};
|
||||
VkPipelineViewportStateCreateInfo viewport_state = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
||||
|
@ -201,7 +203,7 @@ static VkPipeline createPipeline( void )
|
|||
.pColorBlendState = &color_blend,
|
||||
.pDepthStencilState = &depth,
|
||||
//.layout = material->pipeline_layout,
|
||||
.renderPass = vk_core.render_pass,
|
||||
.renderPass = vk_frame.render_pass,
|
||||
.subpass = 0,
|
||||
};
|
||||
|
||||
|
@ -244,6 +246,7 @@ void vk2dBegin( void )
|
|||
{
|
||||
g2d.num_pics = 0;
|
||||
g2d.current_batch = 0;
|
||||
g2d.batch[0].vertex_count = 0;
|
||||
}
|
||||
|
||||
void vk2dEnd( void )
|
||||
|
|
239
ref_vk/vk_core.c
239
ref_vk/vk_core.c
|
@ -4,6 +4,7 @@
|
|||
#include "vk_2d.h"
|
||||
#include "vk_renderstate.h"
|
||||
#include "vk_buffer.h"
|
||||
#include "vk_framectl.h"
|
||||
|
||||
#include "xash3d_types.h"
|
||||
#include "cvardef.h"
|
||||
|
@ -25,23 +26,6 @@
|
|||
X(vkEnumerateInstanceVersion) \
|
||||
X(vkCreateInstance) \
|
||||
|
||||
#define INSTANCE_FUNCS(X) \
|
||||
X(vkDestroyInstance) \
|
||||
X(vkEnumeratePhysicalDevices) \
|
||||
X(vkGetPhysicalDeviceProperties) \
|
||||
X(vkGetPhysicalDeviceProperties2) \
|
||||
X(vkGetPhysicalDeviceFeatures2) \
|
||||
X(vkGetPhysicalDeviceQueueFamilyProperties) \
|
||||
X(vkGetPhysicalDeviceSurfaceSupportKHR) \
|
||||
X(vkGetPhysicalDeviceMemoryProperties) \
|
||||
X(vkGetPhysicalDeviceSurfacePresentModesKHR) \
|
||||
X(vkGetPhysicalDeviceSurfaceFormatsKHR) \
|
||||
X(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \
|
||||
X(vkCreateDevice) \
|
||||
X(vkGetDeviceProcAddr) \
|
||||
X(vkDestroyDevice) \
|
||||
X(vkDestroySurfaceKHR) \
|
||||
|
||||
#define INSTANCE_DEBUG_FUNCS(X) \
|
||||
X(vkCreateDebugUtilsMessengerEXT) \
|
||||
X(vkDestroyDebugUtilsMessengerEXT) \
|
||||
|
@ -140,12 +124,10 @@ VkBool32 debugCallback(
|
|||
// TODO better messages, not only errors, what are other arguments for, ...
|
||||
if (messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
|
||||
gEngine.Con_Printf(S_ERROR "Validation: %s\n", pCallbackData->pMessage);
|
||||
#ifdef DEBUG
|
||||
#ifdef _MSC_VER
|
||||
__debugbreak();
|
||||
#else
|
||||
__builtin_trap();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return VK_FALSE;
|
||||
|
@ -262,7 +244,7 @@ static qboolean createInstance( void )
|
|||
return true;
|
||||
}
|
||||
|
||||
qboolean createDevice( void )
|
||||
qboolean pickAndCreateDevice( void )
|
||||
{
|
||||
VkPhysicalDevice *physical_devices = NULL;
|
||||
uint32_t num_physical_devices = 0;
|
||||
|
@ -296,7 +278,7 @@ qboolean createDevice( void )
|
|||
if (!(queue_family_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT))
|
||||
continue;
|
||||
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], j, vk_core.surface, &present);
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], j, vk_core.surface.surface, &present);
|
||||
|
||||
if (!present)
|
||||
continue;
|
||||
|
@ -358,7 +340,7 @@ qboolean createDevice( void )
|
|||
return true;
|
||||
}
|
||||
|
||||
const char *presentModeName(VkPresentModeKHR present_mode)
|
||||
static const char *presentModeName(VkPresentModeKHR present_mode)
|
||||
{
|
||||
switch (present_mode)
|
||||
{
|
||||
|
@ -372,172 +354,27 @@ const char *presentModeName(VkPresentModeKHR present_mode)
|
|||
}
|
||||
}
|
||||
|
||||
static qboolean createRenderPass( void ) {
|
||||
VkAttachmentDescription attachments[] = {{
|
||||
.format = VK_FORMAT_B8G8R8A8_SRGB,// FIXME too early swapchain.create_info.imageFormat;
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
//.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
//attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
||||
/*}, {
|
||||
// Depth
|
||||
.format = g.depth_format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
//attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
//attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
||||
*/
|
||||
}};
|
||||
|
||||
VkAttachmentReference color_attachment = {
|
||||
.attachment = 0,
|
||||
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
};
|
||||
|
||||
/*
|
||||
VkAttachmentReference depth_attachment = {0};
|
||||
depth_attachment.attachment = 1;
|
||||
depth_attachment.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
*/
|
||||
|
||||
VkSubpassDescription subdesc = {
|
||||
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = &color_attachment,
|
||||
//.pDepthStencilAttachment = &depth_attachment,
|
||||
};
|
||||
|
||||
VkRenderPassCreateInfo rpci = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
||||
.attachmentCount = ARRAYSIZE(attachments),
|
||||
.pAttachments = attachments,
|
||||
.subpassCount = 1,
|
||||
.pSubpasses = &subdesc,
|
||||
};
|
||||
|
||||
XVK_CHECK(vkCreateRenderPass(vk_core.device, &rpci, NULL, &vk_core.render_pass));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static qboolean createSwapchain( void )
|
||||
static qboolean initSurface( void )
|
||||
{
|
||||
VkSwapchainCreateInfoKHR *create_info = &vk_core.swapchain.create_info;
|
||||
XVK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(vk_core.physical_device.device, vk_core.surface.surface, &vk_core.surface.num_present_modes, vk_core.surface.present_modes));
|
||||
vk_core.surface.present_modes = Mem_Malloc(vk_core.pool, sizeof(*vk_core.surface.present_modes) * vk_core.surface.num_present_modes);
|
||||
XVK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(vk_core.physical_device.device, vk_core.surface.surface, &vk_core.surface.num_present_modes, vk_core.surface.present_modes));
|
||||
|
||||
uint32_t num_surface_formats = 0;
|
||||
VkSurfaceFormatKHR *surface_formats = NULL;
|
||||
|
||||
uint32_t num_present_modes = 0;
|
||||
VkPresentModeKHR *present_modes = NULL;
|
||||
|
||||
const uint32_t prev_num_images = vk_core.swapchain.num_images;
|
||||
|
||||
XVK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(vk_core.physical_device.device, vk_core.surface, &num_present_modes, present_modes));
|
||||
present_modes = Mem_Malloc(vk_core.pool, sizeof(*present_modes) * num_present_modes);
|
||||
XVK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(vk_core.physical_device.device, vk_core.surface, &num_present_modes, present_modes));
|
||||
|
||||
gEngine.Con_Reportf("Supported surface present modes: %u\n", num_present_modes);
|
||||
for (uint32_t i = 0; i < num_present_modes; ++i)
|
||||
gEngine.Con_Printf("Supported surface present modes: %u\n", vk_core.surface.num_present_modes);
|
||||
for (uint32_t i = 0; i < vk_core.surface.num_present_modes; ++i)
|
||||
{
|
||||
gEngine.Con_Reportf("\t%u: %s (%u)\n", i, presentModeName(present_modes[i]), present_modes[i]);
|
||||
gEngine.Con_Reportf("\t%u: %s (%u)\n", i, presentModeName(vk_core.surface.present_modes[i]), vk_core.surface.present_modes[i]);
|
||||
}
|
||||
|
||||
XVK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(vk_core.physical_device.device, vk_core.surface, &num_surface_formats, surface_formats));
|
||||
surface_formats = Mem_Malloc(vk_core.pool, sizeof(*surface_formats) * num_surface_formats);
|
||||
XVK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(vk_core.physical_device.device, vk_core.surface, &num_surface_formats, surface_formats));
|
||||
XVK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(vk_core.physical_device.device, vk_core.surface.surface, &vk_core.surface.num_surface_formats, vk_core.surface.surface_formats));
|
||||
vk_core.surface.surface_formats = Mem_Malloc(vk_core.pool, sizeof(*vk_core.surface.surface_formats) * vk_core.surface.num_surface_formats);
|
||||
XVK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(vk_core.physical_device.device, vk_core.surface.surface, &vk_core.surface.num_surface_formats, vk_core.surface.surface_formats));
|
||||
|
||||
gEngine.Con_Reportf("Supported surface formats: %u\n", num_surface_formats);
|
||||
for (uint32_t i = 0; i < num_surface_formats; ++i)
|
||||
gEngine.Con_Reportf("Supported surface formats: %u\n", vk_core.surface.num_surface_formats);
|
||||
for (uint32_t i = 0; i < vk_core.surface.num_surface_formats; ++i)
|
||||
{
|
||||
// TODO symbolicate
|
||||
gEngine.Con_Reportf("\t%u: %u %u\n", surface_formats[i].format, surface_formats[i].colorSpace);
|
||||
}
|
||||
|
||||
XVK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk_core.physical_device.device, vk_core.surface, &vk_core.swapchain.surface_caps));
|
||||
|
||||
create_info->sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||
create_info->pNext = NULL;
|
||||
create_info->surface = vk_core.surface;
|
||||
create_info->imageFormat = VK_FORMAT_B8G8R8A8_SRGB; // TODO get from surface_formats
|
||||
create_info->imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; // TODO get from surface_formats
|
||||
create_info->imageExtent.width = vk_core.swapchain.surface_caps.currentExtent.width;
|
||||
create_info->imageExtent.height = vk_core.swapchain.surface_caps.currentExtent.height;
|
||||
create_info->imageArrayLayers = 1;
|
||||
create_info->imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
create_info->imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
create_info->preTransform = vk_core.swapchain.surface_caps.currentTransform;
|
||||
create_info->compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
create_info->presentMode = VK_PRESENT_MODE_FIFO_KHR; // TODO caps, MAILBOX is better
|
||||
//create_info->presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; // TODO caps, MAILBOX is better
|
||||
create_info->clipped = VK_TRUE;
|
||||
create_info->oldSwapchain = vk_core.swapchain.swapchain;
|
||||
|
||||
create_info->minImageCount = vk_core.swapchain.surface_caps.minImageCount + 3;
|
||||
if (vk_core.swapchain.surface_caps.maxImageCount && create_info->minImageCount > vk_core.swapchain.surface_caps.maxImageCount)
|
||||
create_info->minImageCount = vk_core.swapchain.surface_caps.maxImageCount;
|
||||
|
||||
XVK_CHECK(vkCreateSwapchainKHR(vk_core.device, create_info, NULL, &vk_core.swapchain.swapchain));
|
||||
|
||||
Mem_Free(present_modes);
|
||||
Mem_Free(surface_formats);
|
||||
|
||||
vk_core.swapchain.num_images = 0;
|
||||
XVK_CHECK(vkGetSwapchainImagesKHR(vk_core.device, vk_core.swapchain.swapchain, &vk_core.swapchain.num_images, NULL));
|
||||
if (prev_num_images != vk_core.swapchain.num_images)
|
||||
{
|
||||
if (vk_core.swapchain.images)
|
||||
{
|
||||
Mem_Free(vk_core.swapchain.images);
|
||||
Mem_Free(vk_core.swapchain.image_views);
|
||||
Mem_Free(vk_core.swapchain.framebuffers);
|
||||
}
|
||||
|
||||
vk_core.swapchain.images = Mem_Malloc(vk_core.pool, sizeof(*vk_core.swapchain.images) * vk_core.swapchain.num_images);
|
||||
vk_core.swapchain.image_views = Mem_Malloc(vk_core.pool, sizeof(*vk_core.swapchain.image_views) * vk_core.swapchain.num_images);
|
||||
vk_core.swapchain.framebuffers = Mem_Malloc(vk_core.pool, sizeof(*vk_core.swapchain.framebuffers) * vk_core.swapchain.num_images);
|
||||
}
|
||||
|
||||
XVK_CHECK(vkGetSwapchainImagesKHR(vk_core.device, vk_core.swapchain.swapchain, &vk_core.swapchain.num_images, vk_core.swapchain.images));
|
||||
|
||||
for (uint32_t i = 0; i < vk_core.swapchain.num_images; ++i) {
|
||||
VkImageViewCreateInfo ivci = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
||||
.format = vk_core.swapchain.create_info.imageFormat,
|
||||
.image = vk_core.swapchain.images[i],
|
||||
.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.subresourceRange.levelCount = 1,
|
||||
.subresourceRange.layerCount = 1,
|
||||
};
|
||||
|
||||
XVK_CHECK(vkCreateImageView(vk_core.device, &ivci, NULL, vk_core.swapchain.image_views + i));
|
||||
|
||||
{
|
||||
const VkImageView attachments[] = {
|
||||
vk_core.swapchain.image_views[i],
|
||||
//g.depth_image_view
|
||||
};
|
||||
VkFramebufferCreateInfo fbci = {
|
||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
.renderPass = vk_core.render_pass,
|
||||
.attachmentCount = ARRAYSIZE(attachments),
|
||||
.pAttachments = attachments,
|
||||
.width = vk_core.swapchain.create_info.imageExtent.width,
|
||||
.height = vk_core.swapchain.create_info.imageExtent.height,
|
||||
.layers = 1,
|
||||
};
|
||||
XVK_CHECK(vkCreateFramebuffer(vk_core.device, &fbci, NULL, vk_core.swapchain.framebuffers + i));
|
||||
}
|
||||
gEngine.Con_Reportf("\t%u: %u %u\n", i, vk_core.surface.surface_formats[i].format, vk_core.surface.surface_formats[i].colorSpace);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -631,6 +468,8 @@ static qboolean initDescriptorPool( void )
|
|||
|
||||
qboolean R_VkInit( void )
|
||||
{
|
||||
// FIXME !!!! handle initialization errors properly: destroy what has already been created
|
||||
|
||||
vk_core.debug = !!(gEngine.Sys_CheckParm("-vkdebug") || gEngine.Sys_CheckParm("-gldebug"));
|
||||
|
||||
if( !gEngine.R_Init_Video( REF_VULKAN )) // request Vulkan surface
|
||||
|
@ -664,21 +503,17 @@ qboolean R_VkInit( void )
|
|||
if (!createInstance())
|
||||
return false;
|
||||
|
||||
vk_core.surface = gEngine.VK_CreateSurface(vk_core.instance);
|
||||
if (!vk_core.surface)
|
||||
vk_core.surface.surface = gEngine.VK_CreateSurface(vk_core.instance);
|
||||
if (!vk_core.surface.surface)
|
||||
{
|
||||
gEngine.Con_Printf( S_ERROR "Cannot create Vulkan surface\n" );
|
||||
// FIXME destroy surface
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!createDevice())
|
||||
if (!pickAndCreateDevice())
|
||||
return false;
|
||||
|
||||
if (!createRenderPass())
|
||||
return false;
|
||||
|
||||
if (!createSwapchain())
|
||||
if (!initSurface())
|
||||
return false;
|
||||
|
||||
if (!createCommandPool())
|
||||
|
@ -687,8 +522,6 @@ qboolean R_VkInit( void )
|
|||
if (!createBuffer(&vk_core.staging, 16 * 1024 * 1024, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
|
||||
return false;
|
||||
|
||||
// TODO initAllocator()
|
||||
|
||||
{
|
||||
VkSamplerCreateInfo sci = {
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
|
@ -707,15 +540,18 @@ qboolean R_VkInit( void )
|
|||
XVK_CHECK(vkCreateSampler(vk_core.device, &sci, NULL, &vk_core.default_sampler));
|
||||
}
|
||||
|
||||
// TODO ...
|
||||
if (!initDescriptorPool())
|
||||
return false;
|
||||
|
||||
initTextures();
|
||||
|
||||
if (!initVk2d())
|
||||
if (!VK_FrameCtlInit())
|
||||
return false;
|
||||
|
||||
if (!renderstateInit())
|
||||
// All below need render_pass
|
||||
|
||||
if (!initVk2d())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -723,24 +559,19 @@ qboolean R_VkInit( void )
|
|||
|
||||
void R_VkShutdown( void )
|
||||
{
|
||||
deinitVk2d();
|
||||
|
||||
VK_FrameCtlShutdown();
|
||||
|
||||
destroyTextures();
|
||||
|
||||
renderstateDestroy();
|
||||
deinitVk2d();
|
||||
vkDestroyDescriptorPool(vk_core.device, vk_core.descriptor_pool.pool, NULL);
|
||||
vkDestroyDescriptorSetLayout(vk_core.device, vk_core.descriptor_pool.one_texture_layout, NULL);
|
||||
vkDestroySampler(vk_core.device, vk_core.default_sampler, NULL);
|
||||
destroyBuffer(&vk_core.staging);
|
||||
|
||||
vkDestroyCommandPool(vk_core.device, vk_core.command_pool, NULL);
|
||||
|
||||
for (uint32_t i = 0; i < vk_core.swapchain.num_images; ++i)
|
||||
{
|
||||
vkDestroyImageView(vk_core.device, vk_core.swapchain.image_views[i], NULL);
|
||||
vkDestroyFramebuffer(vk_core.device, vk_core.swapchain.framebuffers[i], NULL);
|
||||
}
|
||||
|
||||
vkDestroySwapchainKHR(vk_core.device, vk_core.swapchain.swapchain, NULL);
|
||||
vkDestroyRenderPass(vk_core.device, vk_core.render_pass, NULL);
|
||||
vkDestroyDevice(vk_core.device, NULL);
|
||||
|
||||
if (vk_core.debug_messenger)
|
||||
|
@ -748,7 +579,9 @@ void R_VkShutdown( void )
|
|||
vkDestroyDebugUtilsMessengerEXT(vk_core.instance, vk_core.debug_messenger, NULL);
|
||||
}
|
||||
|
||||
vkDestroySurfaceKHR(vk_core.instance, vk_core.surface, NULL);
|
||||
Mem_Free(vk_core.surface.present_modes);
|
||||
Mem_Free(vk_core.surface.surface_formats);
|
||||
vkDestroySurfaceKHR(vk_core.instance, vk_core.surface.surface, NULL);
|
||||
vkDestroyInstance(vk_core.instance, NULL);
|
||||
Mem_FreePool(&vk_core.pool);
|
||||
}
|
||||
|
|
|
@ -62,24 +62,19 @@ typedef struct vulkan_core_s {
|
|||
byte *pool;
|
||||
|
||||
qboolean debug;
|
||||
VkSurfaceKHR surface;
|
||||
struct {
|
||||
VkSurfaceKHR surface;
|
||||
uint32_t num_surface_formats;
|
||||
VkSurfaceFormatKHR *surface_formats;
|
||||
|
||||
uint32_t num_present_modes;
|
||||
VkPresentModeKHR *present_modes;
|
||||
} surface;
|
||||
|
||||
physical_device_t physical_device;
|
||||
VkDevice device;
|
||||
VkQueue queue;
|
||||
|
||||
VkRenderPass render_pass;
|
||||
|
||||
struct {
|
||||
VkSurfaceCapabilitiesKHR surface_caps;
|
||||
VkSwapchainCreateInfoKHR create_info;
|
||||
VkSwapchainKHR swapchain;
|
||||
uint32_t num_images;
|
||||
VkImage *images;
|
||||
VkImageView *image_views;
|
||||
VkFramebuffer *framebuffers;
|
||||
} swapchain;
|
||||
|
||||
VkCommandPool command_pool;
|
||||
VkCommandBuffer cb;
|
||||
|
||||
|
@ -103,6 +98,23 @@ const char *resultName(VkResult result);
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
#define INSTANCE_FUNCS(X) \
|
||||
X(vkDestroyInstance) \
|
||||
X(vkEnumeratePhysicalDevices) \
|
||||
X(vkGetPhysicalDeviceProperties) \
|
||||
X(vkGetPhysicalDeviceProperties2) \
|
||||
X(vkGetPhysicalDeviceFeatures2) \
|
||||
X(vkGetPhysicalDeviceQueueFamilyProperties) \
|
||||
X(vkGetPhysicalDeviceSurfaceSupportKHR) \
|
||||
X(vkGetPhysicalDeviceMemoryProperties) \
|
||||
X(vkGetPhysicalDeviceSurfacePresentModesKHR) \
|
||||
X(vkGetPhysicalDeviceSurfaceFormatsKHR) \
|
||||
X(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \
|
||||
X(vkCreateDevice) \
|
||||
X(vkGetDeviceProcAddr) \
|
||||
X(vkDestroyDevice) \
|
||||
X(vkDestroySurfaceKHR) \
|
||||
|
||||
#define DEVICE_FUNCS(X) \
|
||||
X(vkGetDeviceQueue) \
|
||||
X(vkCreateSwapchainKHR) \
|
||||
|
@ -163,7 +175,9 @@ const char *resultName(VkResult result);
|
|||
X(vkCreateDescriptorSetLayout) \
|
||||
X(vkAllocateDescriptorSets) \
|
||||
X(vkUpdateDescriptorSets) \
|
||||
X(vkDestroyDescriptorSetLayout) \
|
||||
|
||||
#define X(f) extern PFN_##f f;
|
||||
DEVICE_FUNCS(X)
|
||||
INSTANCE_FUNCS(X)
|
||||
#undef X
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
#include "vk_framectl.h"
|
||||
|
||||
#include "vk_2d.h"
|
||||
|
||||
#include "eiface.h"
|
||||
|
||||
vk_framectl_t vk_frame = {0};
|
||||
|
||||
static struct
|
||||
{
|
||||
VkSemaphore image_available;
|
||||
VkSemaphore done;
|
||||
VkFence fence;
|
||||
} g_frame;
|
||||
|
||||
static qboolean createRenderPass( void ) {
|
||||
VkAttachmentDescription attachments[] = {{
|
||||
.format = VK_FORMAT_B8G8R8A8_SRGB,// FIXME too early swapchain.create_info.imageFormat;
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
//.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
//attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
||||
/*}, {
|
||||
// Depth
|
||||
.format = g.depth_format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
//attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
//attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
||||
*/
|
||||
}};
|
||||
|
||||
VkAttachmentReference color_attachment = {
|
||||
.attachment = 0,
|
||||
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
};
|
||||
|
||||
/*
|
||||
VkAttachmentReference depth_attachment = {0};
|
||||
depth_attachment.attachment = 1;
|
||||
depth_attachment.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
*/
|
||||
|
||||
VkSubpassDescription subdesc = {
|
||||
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = &color_attachment,
|
||||
//.pDepthStencilAttachment = &depth_attachment,
|
||||
};
|
||||
|
||||
VkRenderPassCreateInfo rpci = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
||||
.attachmentCount = ARRAYSIZE(attachments),
|
||||
.pAttachments = attachments,
|
||||
.subpassCount = 1,
|
||||
.pSubpasses = &subdesc,
|
||||
};
|
||||
|
||||
XVK_CHECK(vkCreateRenderPass(vk_core.device, &rpci, NULL, &vk_frame.render_pass));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static qboolean createSwapchain( void )
|
||||
{
|
||||
VkSwapchainCreateInfoKHR *create_info = &vk_frame.create_info;
|
||||
const uint32_t prev_num_images = vk_frame.num_images;
|
||||
|
||||
XVK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk_core.physical_device.device, vk_core.surface.surface, &vk_frame.surface_caps));
|
||||
|
||||
create_info->sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||
create_info->pNext = NULL;
|
||||
create_info->surface = vk_core.surface.surface;
|
||||
create_info->imageFormat = VK_FORMAT_B8G8R8A8_SRGB; // TODO get from surface_formats
|
||||
create_info->imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; // TODO get from surface_formats
|
||||
create_info->imageExtent.width = vk_frame.surface_caps.currentExtent.width;
|
||||
create_info->imageExtent.height = vk_frame.surface_caps.currentExtent.height;
|
||||
create_info->imageArrayLayers = 1;
|
||||
create_info->imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
create_info->imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
create_info->preTransform = vk_frame.surface_caps.currentTransform;
|
||||
create_info->compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
create_info->presentMode = VK_PRESENT_MODE_FIFO_KHR; // TODO caps, MAILBOX is better
|
||||
//create_info->presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; // TODO caps, MAILBOX is better
|
||||
create_info->clipped = VK_TRUE;
|
||||
create_info->oldSwapchain = vk_frame.swapchain;
|
||||
|
||||
create_info->minImageCount = vk_frame.surface_caps.minImageCount + 3;
|
||||
if (vk_frame.surface_caps.maxImageCount && create_info->minImageCount > vk_frame.surface_caps.maxImageCount)
|
||||
create_info->minImageCount = vk_frame.surface_caps.maxImageCount;
|
||||
|
||||
XVK_CHECK(vkCreateSwapchainKHR(vk_core.device, create_info, NULL, &vk_frame.swapchain));
|
||||
|
||||
vk_frame.num_images = 0;
|
||||
XVK_CHECK(vkGetSwapchainImagesKHR(vk_core.device, vk_frame.swapchain, &vk_frame.num_images, NULL));
|
||||
if (prev_num_images != vk_frame.num_images)
|
||||
{
|
||||
if (vk_frame.images)
|
||||
{
|
||||
Mem_Free(vk_frame.images);
|
||||
Mem_Free(vk_frame.image_views);
|
||||
Mem_Free(vk_frame.framebuffers);
|
||||
}
|
||||
|
||||
vk_frame.images = Mem_Malloc(vk_core.pool, sizeof(*vk_frame.images) * vk_frame.num_images);
|
||||
vk_frame.image_views = Mem_Malloc(vk_core.pool, sizeof(*vk_frame.image_views) * vk_frame.num_images);
|
||||
vk_frame.framebuffers = Mem_Malloc(vk_core.pool, sizeof(*vk_frame.framebuffers) * vk_frame.num_images);
|
||||
}
|
||||
|
||||
XVK_CHECK(vkGetSwapchainImagesKHR(vk_core.device, vk_frame.swapchain, &vk_frame.num_images, vk_frame.images));
|
||||
|
||||
for (uint32_t i = 0; i < vk_frame.num_images; ++i) {
|
||||
VkImageViewCreateInfo ivci = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
|
||||
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
||||
.format = vk_frame.create_info.imageFormat,
|
||||
.image = vk_frame.images[i],
|
||||
.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.subresourceRange.levelCount = 1,
|
||||
.subresourceRange.layerCount = 1,
|
||||
};
|
||||
|
||||
XVK_CHECK(vkCreateImageView(vk_core.device, &ivci, NULL, vk_frame.image_views + i));
|
||||
|
||||
{
|
||||
const VkImageView attachments[] = {
|
||||
vk_frame.image_views[i],
|
||||
//g.depth_image_view
|
||||
};
|
||||
VkFramebufferCreateInfo fbci = {
|
||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
.renderPass = vk_frame.render_pass,
|
||||
.attachmentCount = ARRAYSIZE(attachments),
|
||||
.pAttachments = attachments,
|
||||
.width = vk_frame.create_info.imageExtent.width,
|
||||
.height = vk_frame.create_info.imageExtent.height,
|
||||
.layers = 1,
|
||||
};
|
||||
XVK_CHECK(vkCreateFramebuffer(vk_core.device, &fbci, NULL, vk_frame.framebuffers + i));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void R_BeginFrame( qboolean clearScene )
|
||||
{
|
||||
gEngine.Con_Printf(S_WARN "VK FIXME: %s(%d)\n", __FUNCTION__, clearScene);
|
||||
vk2dBegin();
|
||||
}
|
||||
|
||||
void R_RenderScene( void )
|
||||
{
|
||||
gEngine.Con_Printf(S_WARN "VK FIXME: %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void R_EndFrame( void )
|
||||
{
|
||||
//gEngine.Con_Printf(S_WARN "VK FIXME: %s\n", __FUNCTION__);
|
||||
|
||||
uint32_t swapchain_image_index;
|
||||
VkClearValue clear_value[] = {
|
||||
{.color = {{1., 0., 0., 0.}}},
|
||||
//{.depthStencil = {1., 0.}}
|
||||
};
|
||||
VkRenderPassBeginInfo rpbi = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.renderPass = vk_frame.render_pass,
|
||||
.renderArea.extent.width = vk_frame.create_info.imageExtent.width,
|
||||
.renderArea.extent.height = vk_frame.create_info.imageExtent.height,
|
||||
.clearValueCount = ARRAYSIZE(clear_value),
|
||||
.pClearValues = clear_value,
|
||||
};
|
||||
VkPipelineStageFlags stageflags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
VkSubmitInfo subinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.pNext = NULL,
|
||||
.commandBufferCount = 1,
|
||||
.pCommandBuffers = &vk_core.cb,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &g_frame.image_available,
|
||||
.signalSemaphoreCount = 1,
|
||||
.pSignalSemaphores = &g_frame.done,
|
||||
.pWaitDstStageMask = &stageflags,
|
||||
};
|
||||
VkPresentInfoKHR presinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.pSwapchains = &vk_frame.swapchain,
|
||||
.pImageIndices = &swapchain_image_index,
|
||||
.swapchainCount = 1,
|
||||
.pWaitSemaphores = &g_frame.done,
|
||||
.waitSemaphoreCount = 1,
|
||||
};
|
||||
|
||||
XVK_CHECK(vkAcquireNextImageKHR(vk_core.device, vk_frame.swapchain, UINT64_MAX, g_frame.image_available,
|
||||
VK_NULL_HANDLE, &swapchain_image_index));
|
||||
rpbi.framebuffer = vk_frame.framebuffers[swapchain_image_index];
|
||||
|
||||
|
||||
{
|
||||
VkCommandBufferBeginInfo beginfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
};
|
||||
XVK_CHECK(vkBeginCommandBuffer(vk_core.cb, &beginfo));
|
||||
}
|
||||
|
||||
vkCmdBeginRenderPass(vk_core.cb, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
vk2dEnd();
|
||||
|
||||
vkCmdEndRenderPass(vk_core.cb);
|
||||
XVK_CHECK(vkEndCommandBuffer(vk_core.cb));
|
||||
|
||||
XVK_CHECK(vkQueueSubmit(vk_core.queue, 1, &subinfo, g_frame.fence));
|
||||
XVK_CHECK(vkQueuePresentKHR(vk_core.queue, &presinfo));
|
||||
|
||||
// TODO bad sync
|
||||
XVK_CHECK(vkWaitForFences(vk_core.device, 1, &g_frame.fence, VK_TRUE, INT64_MAX));
|
||||
XVK_CHECK(vkResetFences(vk_core.device, 1, &g_frame.fence));
|
||||
}
|
||||
|
||||
qboolean VK_FrameCtlInit( void )
|
||||
{
|
||||
if (!createRenderPass())
|
||||
return false;
|
||||
|
||||
if (!createSwapchain())
|
||||
return false;
|
||||
|
||||
g_frame.image_available = createSemaphore();
|
||||
g_frame.done = createSemaphore();
|
||||
g_frame.fence = createFence();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VK_FrameCtlShutdown( void )
|
||||
{
|
||||
destroyFence(g_frame.fence);
|
||||
destroySemaphore(g_frame.done);
|
||||
destroySemaphore(g_frame.image_available);
|
||||
|
||||
for (uint32_t i = 0; i < vk_frame.num_images; ++i)
|
||||
{
|
||||
vkDestroyImageView(vk_core.device, vk_frame.image_views[i], NULL);
|
||||
vkDestroyFramebuffer(vk_core.device, vk_frame.framebuffers[i], NULL);
|
||||
}
|
||||
|
||||
vkDestroySwapchainKHR(vk_core.device, vk_frame.swapchain, NULL);
|
||||
vkDestroyRenderPass(vk_core.device, vk_frame.render_pass, NULL);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
#include "vk_core.h"
|
||||
|
||||
#include "xash3d_types.h"
|
||||
|
||||
typedef struct vk_framectl_s {
|
||||
VkRenderPass render_pass;
|
||||
|
||||
VkSurfaceCapabilitiesKHR surface_caps;
|
||||
VkSwapchainCreateInfoKHR create_info;
|
||||
VkSwapchainKHR swapchain;
|
||||
uint32_t num_images;
|
||||
VkImage *images;
|
||||
VkImageView *image_views;
|
||||
VkFramebuffer *framebuffers;
|
||||
} vk_framectl_t;
|
||||
|
||||
extern vk_framectl_t vk_frame;
|
||||
|
||||
qboolean VK_FrameCtlInit( void );
|
||||
void VK_FrameCtlShutdown( void );
|
||||
|
||||
void R_BeginFrame( qboolean clearScene );
|
||||
void R_RenderScene( void );
|
||||
void R_EndFrame( void );
|
|
@ -21,13 +21,6 @@ typedef struct render_state_s {
|
|||
int blending_mode; // kRenderNormal, ...
|
||||
} render_state_t;
|
||||
|
||||
static struct
|
||||
{
|
||||
VkSemaphore image_available;
|
||||
VkSemaphore done;
|
||||
VkFence fence;
|
||||
} grs;
|
||||
|
||||
render_state_t render_state = {0};
|
||||
|
||||
static const char *renderModeName(int mode)
|
||||
|
@ -70,95 +63,3 @@ void R_Set2DMode( qboolean enable )
|
|||
render_state.mode_2d = enable;
|
||||
}
|
||||
|
||||
void R_BeginFrame( qboolean clearScene )
|
||||
{
|
||||
gEngine.Con_Printf(S_WARN "VK FIXME: %s(%d)\n", __FUNCTION__, clearScene);
|
||||
vk2dBegin();
|
||||
}
|
||||
|
||||
void R_RenderScene( void )
|
||||
{
|
||||
gEngine.Con_Printf(S_WARN "VK FIXME: %s\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void R_EndFrame( void )
|
||||
{
|
||||
//gEngine.Con_Printf(S_WARN "VK FIXME: %s\n", __FUNCTION__);
|
||||
|
||||
uint32_t swapchain_image_index;
|
||||
VkClearValue clear_value[] = {
|
||||
{.color = {{1., 0., 0., 0.}}},
|
||||
//{.depthStencil = {1., 0.}}
|
||||
};
|
||||
VkRenderPassBeginInfo rpbi = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.renderPass = vk_core.render_pass,
|
||||
.renderArea.extent.width = vk_core.swapchain.create_info.imageExtent.width,
|
||||
.renderArea.extent.height = vk_core.swapchain.create_info.imageExtent.height,
|
||||
.clearValueCount = ARRAYSIZE(clear_value),
|
||||
.pClearValues = clear_value,
|
||||
};
|
||||
VkPipelineStageFlags stageflags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
VkSubmitInfo subinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.pNext = NULL,
|
||||
.commandBufferCount = 1,
|
||||
.pCommandBuffers = &vk_core.cb,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &grs.image_available,
|
||||
.signalSemaphoreCount = 1,
|
||||
.pSignalSemaphores = &grs.done,
|
||||
.pWaitDstStageMask = &stageflags,
|
||||
};
|
||||
VkPresentInfoKHR presinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.pSwapchains = &vk_core.swapchain.swapchain,
|
||||
.pImageIndices = &swapchain_image_index,
|
||||
.swapchainCount = 1,
|
||||
.pWaitSemaphores = &grs.done,
|
||||
.waitSemaphoreCount = 1,
|
||||
};
|
||||
|
||||
XVK_CHECK(vkAcquireNextImageKHR(vk_core.device, vk_core.swapchain.swapchain, UINT64_MAX, grs.image_available,
|
||||
VK_NULL_HANDLE, &swapchain_image_index));
|
||||
rpbi.framebuffer = vk_core.swapchain.framebuffers[swapchain_image_index];
|
||||
|
||||
|
||||
{
|
||||
VkCommandBufferBeginInfo beginfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
};
|
||||
XVK_CHECK(vkBeginCommandBuffer(vk_core.cb, &beginfo));
|
||||
}
|
||||
|
||||
vkCmdBeginRenderPass(vk_core.cb, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
vk2dEnd();
|
||||
|
||||
vkCmdEndRenderPass(vk_core.cb);
|
||||
XVK_CHECK(vkEndCommandBuffer(vk_core.cb));
|
||||
|
||||
XVK_CHECK(vkQueueSubmit(vk_core.queue, 1, &subinfo, grs.fence));
|
||||
XVK_CHECK(vkQueuePresentKHR(vk_core.queue, &presinfo));
|
||||
|
||||
// TODO bad sync
|
||||
XVK_CHECK(vkWaitForFences(vk_core.device, 1, &grs.fence, VK_TRUE, INT64_MAX));
|
||||
XVK_CHECK(vkResetFences(vk_core.device, 1, &grs.fence));
|
||||
}
|
||||
|
||||
qboolean renderstateInit( void )
|
||||
{
|
||||
grs.image_available = createSemaphore();
|
||||
grs.done = createSemaphore();
|
||||
grs.fence = createFence();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void renderstateDestroy( void )
|
||||
{
|
||||
destroyFence(grs.fence);
|
||||
destroySemaphore(grs.done);
|
||||
destroySemaphore(grs.image_available);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,3 @@ void R_Set2DMode( qboolean enable );
|
|||
void R_BeginFrame( qboolean clearScene );
|
||||
void R_RenderScene( void );
|
||||
void R_EndFrame( void );
|
||||
|
||||
qboolean renderstateInit( void );
|
||||
void renderstateDestroy( void );
|
||||
|
|
Loading…
Reference in New Issue