diff --git a/src/engine/platform/win_glimp.c b/src/engine/platform/win_glimp.c index 2857f9c..4926bf1 100644 --- a/src/engine/platform/win_glimp.c +++ b/src/engine/platform/win_glimp.c @@ -563,20 +563,23 @@ static bool GLW_SetMode(int mode, qboolean fullscreen) { if (r_renderAPICompareWindow->integer) { HWND hwnd2 = create_api_compare_window(glConfig.vidWidth, glConfig.vidHeight); - if (!vk_initialize(hwnd2)) { + vk_initialize(hwnd2); + g_wv.hWnd_vulkan = hwnd2; + /*if (!vk_initialize(hwnd2)) { ShowWindow(hwnd2, SW_HIDE); DestroyWindow(hwnd2); ri.Printf(PRINT_WARNING, "GLW_SetMode: could not create API compare window"); } else { g_wv.hWnd_vulkan = hwnd2; - } + }*/ } } else { // vulkan - if (!vk_initialize(hwnd)) { + vk_initialize(hwnd); + /*if (!vk_initialize(hwnd)) { ShowWindow(hwnd, SW_HIDE); DestroyWindow(hwnd); return false; - } + }*/ g_wv.hWnd = hwnd; g_wv.hWnd_vulkan = hwnd; diff --git a/src/engine/renderer/vk.cpp b/src/engine/renderer/vk.cpp index e72274d..65a4a2c 100644 --- a/src/engine/renderer/vk.cpp +++ b/src/engine/renderer/vk.cpp @@ -543,341 +543,333 @@ static void deallocate_image_chunks() { VkPipeline create_pipeline(const Vk_Pipeline_Desc&); -bool vk_initialize(HWND hwnd) { +void vk_initialize(HWND hwnd) { vk_log_file = fopen("vk_dev.log", "w"); - try { - auto& g = vk; + vk.instance = create_instance(); + vk.physical_device = select_physical_device(vk.instance); + vk.surface = create_surface(vk.instance, hwnd); + vk.surface_format = select_surface_format(vk.physical_device, vk.surface); - g.instance = create_instance(); - g.physical_device = select_physical_device(g.instance); - g.surface = create_surface(g.instance, hwnd); - g.surface_format = select_surface_format(g.physical_device, g.surface); + vk.queue_family_index = select_queue_family(vk.physical_device, vk.surface); + vk.device = create_device(vk.physical_device, vk.queue_family_index); + vkGetDeviceQueue(vk.device, vk.queue_family_index, 0, &vk.queue); - g.queue_family_index = select_queue_family(g.physical_device, g.surface); - g.device = create_device(g.physical_device, g.queue_family_index); - vkGetDeviceQueue(g.device, g.queue_family_index, 0, &g.queue); + vk.swapchain = create_swapchain(vk.physical_device, vk.device, vk.surface, vk.surface_format); - g.swapchain = create_swapchain(g.physical_device, g.device, g.surface, g.surface_format); + VK_CHECK(vkGetSwapchainImagesKHR(vk.device, vk.swapchain, &vk.swapchain_image_count, nullptr)); - VK_CHECK(vkGetSwapchainImagesKHR(g.device, g.swapchain, &vk.swapchain_image_count, nullptr)); + if (vk.swapchain_image_count > MAX_SWAPCHAIN_IMAGES) + ri.Error( ERR_FATAL, "initialize_vulkan: swapchain image count (%d) exceeded limit (%d)", vk.swapchain_image_count, MAX_SWAPCHAIN_IMAGES ); - if (vk.swapchain_image_count > MAX_SWAPCHAIN_IMAGES) - ri.Error( ERR_FATAL, "initialize_vulkan: swapchain image count (%d) exceeded limit (%d)", vk.swapchain_image_count, MAX_SWAPCHAIN_IMAGES ); + VK_CHECK(vkGetSwapchainImagesKHR(vk.device, vk.swapchain, &vk.swapchain_image_count, vk.swapchain_images)); - VK_CHECK(vkGetSwapchainImagesKHR(g.device, g.swapchain, &vk.swapchain_image_count, g.swapchain_images)); - - for (std::size_t i = 0; i < vk.swapchain_image_count; i++) { - VkImageViewCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - desc.image = g.swapchain_images[i]; - desc.viewType = VK_IMAGE_VIEW_TYPE_2D; - desc.format = g.surface_format.format; - desc.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; - desc.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; - desc.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; - desc.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; - desc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - desc.subresourceRange.baseMipLevel = 0; - desc.subresourceRange.levelCount = 1; - desc.subresourceRange.baseArrayLayer = 0; - desc.subresourceRange.layerCount = 1; - VK_CHECK(vkCreateImageView(g.device, &desc, nullptr, &g.swapchain_image_views[i])); - } - - { - VkCommandPoolCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - desc.queueFamilyIndex = vk.queue_family_index; - - VK_CHECK(vkCreateCommandPool(g.device, &desc, nullptr, &vk.command_pool)); - } - - { - VkCommandBufferAllocateInfo alloc_info; - alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - alloc_info.pNext = nullptr; - alloc_info.commandPool = vk.command_pool; - alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - alloc_info.commandBufferCount = 1; - VK_CHECK(vkAllocateCommandBuffers(vk.device, &alloc_info, &g.command_buffer)); - } - - // - // Depth attachment image. - // - { - VkFormat depth_format = find_depth_format(vk.physical_device); - - VkImageCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - desc.imageType = VK_IMAGE_TYPE_2D; - desc.format = depth_format; - desc.extent.width = glConfig.vidWidth; - desc.extent.height = glConfig.vidHeight; - desc.extent.depth = 1; - desc.mipLevels = 1; - desc.arrayLayers = 1; - desc.samples = VK_SAMPLE_COUNT_1_BIT; - desc.tiling = VK_IMAGE_TILING_OPTIMAL; - desc.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - desc.queueFamilyIndexCount = 0; - desc.pQueueFamilyIndices = nullptr; - desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - - VK_CHECK(vkCreateImage(vk.device, &desc, nullptr, &vk.depth_image)); - - VkMemoryRequirements memory_requirements; - vkGetImageMemoryRequirements(vk.device, vk.depth_image, &memory_requirements); - - VkMemoryAllocateInfo alloc_info; - alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - alloc_info.pNext = nullptr; - alloc_info.allocationSize = memory_requirements.size; - alloc_info.memoryTypeIndex = find_memory_type(vk.physical_device, memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - - VK_CHECK(vkAllocateMemory(vk.device, &alloc_info, nullptr, &vk.depth_image_memory)); - VK_CHECK(vkBindImageMemory(vk.device, vk.depth_image, vk.depth_image_memory, 0)); - vk.depth_image_view = create_image_view(vk.depth_image, depth_format, VK_IMAGE_ASPECT_DEPTH_BIT); - - record_and_run_commands(vk.command_pool, vk.queue, [&depth_format](VkCommandBuffer command_buffer) { - record_image_layout_transition(command_buffer, vk.depth_image, depth_format, 0, VK_IMAGE_LAYOUT_UNDEFINED, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - }); - } - - VkFormat depth_format = find_depth_format(vk.physical_device); - - vk.render_pass = create_render_pass(vk.device, vk.surface_format.format, depth_format); - - { - VkImageView attachments[2] = {VK_NULL_HANDLE, vk.depth_image_view}; - - VkFramebufferCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - desc.renderPass = vk.render_pass; - desc.attachmentCount = 2; - desc.pAttachments = attachments; - desc.width = glConfig.vidWidth; - desc.height = glConfig.vidHeight; - desc.layers = 1; - - for (uint32_t i = 0; i < vk.swapchain_image_count; i++) { - attachments[0] = vk.swapchain_image_views[i]; // set color attachment - VK_CHECK(vkCreateFramebuffer(vk.device, &desc, nullptr, &vk.framebuffers[i])); - } - } - - // - // Descriptor pool. - // - { - VkDescriptorPoolSize pool_size; - pool_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - pool_size.descriptorCount = MAX_DRAWIMAGES; - - VkDescriptorPoolCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - desc.maxSets = MAX_DRAWIMAGES; - desc.poolSizeCount = 1; - desc.pPoolSizes = &pool_size; - - VK_CHECK(vkCreateDescriptorPool(vk.device, &desc, nullptr, &vk.descriptor_pool)); - } - - // - // Descriptor set layout. - // - { - VkDescriptorSetLayoutBinding descriptor_binding; - descriptor_binding.binding = 0; - descriptor_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptor_binding.descriptorCount = 1; - descriptor_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - descriptor_binding.pImmutableSamplers = nullptr; - - VkDescriptorSetLayoutCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - desc.bindingCount = 1; - desc.pBindings = &descriptor_binding; - - VK_CHECK(vkCreateDescriptorSetLayout(vk.device, &desc, nullptr, &vk.set_layout)); - } - - // - // Pipeline layout. - // - { - VkPushConstantRange push_range; - push_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - push_range.offset = 0; - push_range.size = 64; // sizeof(float[16]) - - VkDescriptorSetLayout set_layouts[2] = {vk.set_layout, vk.set_layout}; - - VkPipelineLayoutCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - desc.setLayoutCount = 2; - desc.pSetLayouts = set_layouts; - desc.pushConstantRangeCount = 1; - desc.pPushConstantRanges = &push_range; - - VK_CHECK(vkCreatePipelineLayout(vk.device, &desc, nullptr, &vk.pipeline_layout)); - } - - // - // Geometry buffers. - // - { - VkBufferCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - desc.queueFamilyIndexCount = 0; - desc.pQueueFamilyIndices = nullptr; - - desc.size = VERTEX_BUFFER_SIZE; - desc.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - VK_CHECK(vkCreateBuffer(vk.device, &desc, nullptr, &vk.vertex_buffer)); - - desc.size = INDEX_BUFFER_SIZE; - desc.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; - VK_CHECK(vkCreateBuffer(vk.device, &desc, nullptr, &vk.index_buffer)); - - VkMemoryRequirements vb_memory_requirements; - vkGetBufferMemoryRequirements(vk.device, vk.vertex_buffer, &vb_memory_requirements); - - VkMemoryRequirements ib_memory_requirements; - vkGetBufferMemoryRequirements(vk.device, vk.index_buffer, &ib_memory_requirements); - - VkDeviceSize mask = ~(ib_memory_requirements.alignment - 1); - VkDeviceSize index_buffer_offset = (vb_memory_requirements.size + ib_memory_requirements.alignment - 1) & mask; - - uint32_t memory_type_bits = vb_memory_requirements.memoryTypeBits & ib_memory_requirements.memoryTypeBits; - uint32_t memory_type = find_memory_type(vk.physical_device, memory_type_bits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - - VkMemoryAllocateInfo alloc_info; - alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - alloc_info.pNext = nullptr; - alloc_info.allocationSize = index_buffer_offset + ib_memory_requirements.size; - alloc_info.memoryTypeIndex = memory_type; - VK_CHECK(vkAllocateMemory(vk.device, &alloc_info, nullptr, &vk.geometry_buffer_memory)); - - vkBindBufferMemory(vk.device, vk.vertex_buffer, vk.geometry_buffer_memory, 0); - vkBindBufferMemory(vk.device, vk.index_buffer, vk.geometry_buffer_memory, index_buffer_offset); - - void* data; - VK_CHECK(vkMapMemory(vk.device, vk.geometry_buffer_memory, 0, VK_WHOLE_SIZE, 0, &data)); - vk.vertex_buffer_ptr = (byte*)data; - vk.index_buffer_ptr = (byte*)data + index_buffer_offset; - } - - // - // Sync primitives. - // - { - VkSemaphoreCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - - VK_CHECK(vkCreateSemaphore(vk.device, &desc, nullptr, &vk.image_acquired)); - VK_CHECK(vkCreateSemaphore(vk.device, &desc, nullptr, &vk.rendering_finished)); - - VkFenceCreateInfo fence_desc; - fence_desc.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fence_desc.pNext = nullptr; - fence_desc.flags = VK_FENCE_CREATE_SIGNALED_BIT; - VK_CHECK(vkCreateFence(vk.device, &fence_desc, nullptr, &vk.rendering_finished_fence)); - } - - // - // Shader modules. - // - { - auto create_shader_module = [](uint8_t* bytes, int count) { - if (count % 4 != 0) { - ri.Error(ERR_FATAL, "Vulkan error: SPIR-V binary buffer size is not multiple of 4"); - } - VkShaderModuleCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - desc.codeSize = count; - desc.pCode = reinterpret_cast(bytes); - - VkShaderModule module; - VK_CHECK(vkCreateShaderModule(vk.device, &desc, nullptr, &module)); - return module; - }; - - vk.single_texture_vs = create_shader_module(single_texture_vert_spv, single_texture_vert_spv_size); - vk.single_texture_fs = create_shader_module(single_texture_frag_spv, single_texture_frag_spv_size); - vk.multi_texture_vs = create_shader_module(multi_texture_vert_spv, multi_texture_vert_spv_size); - vk.multi_texture_mul_fs = create_shader_module(multi_texture_mul_frag_spv, multi_texture_mul_frag_spv_size); - vk.multi_texture_add_fs = create_shader_module(multi_texture_add_frag_spv, multi_texture_add_frag_spv_size); - } - - // - // Samplers. - // - { - VkSamplerCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - desc.magFilter = VK_FILTER_LINEAR; - desc.minFilter = VK_FILTER_LINEAR; - desc.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - desc.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - desc.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - desc.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - desc.mipLodBias = 0.0f; - desc.anisotropyEnable = VK_TRUE; - desc.maxAnisotropy = 1; - desc.compareEnable = VK_FALSE; - desc.compareOp = VK_COMPARE_OP_ALWAYS; - desc.minLod = 0.0f; - desc.maxLod = 0.0f; - desc.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; - desc.unnormalizedCoordinates = VK_FALSE; - - VK_CHECK(vkCreateSampler(vk.device, &desc, nullptr, &vk.sampler)); - } - - // - // Skybox pipeline. - // - { - Vk_Pipeline_Desc desc; - desc.shader_type = Vk_Shader_Type::single_texture; - desc.state_bits = 0; - desc.face_culling = CT_FRONT_SIDED; - desc.polygon_offset = false; - - vk.skybox_pipeline = create_pipeline(desc); - } - - } catch (const std::exception&) { - return false; + for (std::size_t i = 0; i < vk.swapchain_image_count; i++) { + VkImageViewCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + desc.image = vk.swapchain_images[i]; + desc.viewType = VK_IMAGE_VIEW_TYPE_2D; + desc.format = vk.surface_format.format; + desc.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + desc.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + desc.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + desc.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + desc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + desc.subresourceRange.baseMipLevel = 0; + desc.subresourceRange.levelCount = 1; + desc.subresourceRange.baseArrayLayer = 0; + desc.subresourceRange.layerCount = 1; + VK_CHECK(vkCreateImageView(vk.device, &desc, nullptr, &vk.swapchain_image_views[i])); + } + + { + VkCommandPoolCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + desc.queueFamilyIndex = vk.queue_family_index; + + VK_CHECK(vkCreateCommandPool(vk.device, &desc, nullptr, &vk.command_pool)); + } + + { + VkCommandBufferAllocateInfo alloc_info; + alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + alloc_info.pNext = nullptr; + alloc_info.commandPool = vk.command_pool; + alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + alloc_info.commandBufferCount = 1; + VK_CHECK(vkAllocateCommandBuffers(vk.device, &alloc_info, &vk.command_buffer)); + } + + // + // Depth attachment image. + // + { + VkFormat depth_format = find_depth_format(vk.physical_device); + + VkImageCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + desc.imageType = VK_IMAGE_TYPE_2D; + desc.format = depth_format; + desc.extent.width = glConfig.vidWidth; + desc.extent.height = glConfig.vidHeight; + desc.extent.depth = 1; + desc.mipLevels = 1; + desc.arrayLayers = 1; + desc.samples = VK_SAMPLE_COUNT_1_BIT; + desc.tiling = VK_IMAGE_TILING_OPTIMAL; + desc.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + desc.queueFamilyIndexCount = 0; + desc.pQueueFamilyIndices = nullptr; + desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + VK_CHECK(vkCreateImage(vk.device, &desc, nullptr, &vk.depth_image)); + + VkMemoryRequirements memory_requirements; + vkGetImageMemoryRequirements(vk.device, vk.depth_image, &memory_requirements); + + VkMemoryAllocateInfo alloc_info; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.pNext = nullptr; + alloc_info.allocationSize = memory_requirements.size; + alloc_info.memoryTypeIndex = find_memory_type(vk.physical_device, memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + VK_CHECK(vkAllocateMemory(vk.device, &alloc_info, nullptr, &vk.depth_image_memory)); + VK_CHECK(vkBindImageMemory(vk.device, vk.depth_image, vk.depth_image_memory, 0)); + vk.depth_image_view = create_image_view(vk.depth_image, depth_format, VK_IMAGE_ASPECT_DEPTH_BIT); + + record_and_run_commands(vk.command_pool, vk.queue, [&depth_format](VkCommandBuffer command_buffer) { + record_image_layout_transition(command_buffer, vk.depth_image, depth_format, 0, VK_IMAGE_LAYOUT_UNDEFINED, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + }); + } + + VkFormat depth_format = find_depth_format(vk.physical_device); + + vk.render_pass = create_render_pass(vk.device, vk.surface_format.format, depth_format); + + { + VkImageView attachments[2] = {VK_NULL_HANDLE, vk.depth_image_view}; + + VkFramebufferCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + desc.renderPass = vk.render_pass; + desc.attachmentCount = 2; + desc.pAttachments = attachments; + desc.width = glConfig.vidWidth; + desc.height = glConfig.vidHeight; + desc.layers = 1; + + for (uint32_t i = 0; i < vk.swapchain_image_count; i++) { + attachments[0] = vk.swapchain_image_views[i]; // set color attachment + VK_CHECK(vkCreateFramebuffer(vk.device, &desc, nullptr, &vk.framebuffers[i])); + } + } + + // + // Descriptor pool. + // + { + VkDescriptorPoolSize pool_size; + pool_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + pool_size.descriptorCount = MAX_DRAWIMAGES; + + VkDescriptorPoolCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + desc.maxSets = MAX_DRAWIMAGES; + desc.poolSizeCount = 1; + desc.pPoolSizes = &pool_size; + + VK_CHECK(vkCreateDescriptorPool(vk.device, &desc, nullptr, &vk.descriptor_pool)); + } + + // + // Descriptor set layout. + // + { + VkDescriptorSetLayoutBinding descriptor_binding; + descriptor_binding.binding = 0; + descriptor_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptor_binding.descriptorCount = 1; + descriptor_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + descriptor_binding.pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + desc.bindingCount = 1; + desc.pBindings = &descriptor_binding; + + VK_CHECK(vkCreateDescriptorSetLayout(vk.device, &desc, nullptr, &vk.set_layout)); + } + + // + // Pipeline layout. + // + { + VkPushConstantRange push_range; + push_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + push_range.offset = 0; + push_range.size = 64; // sizeof(float[16]) + + VkDescriptorSetLayout set_layouts[2] = {vk.set_layout, vk.set_layout}; + + VkPipelineLayoutCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + desc.setLayoutCount = 2; + desc.pSetLayouts = set_layouts; + desc.pushConstantRangeCount = 1; + desc.pPushConstantRanges = &push_range; + + VK_CHECK(vkCreatePipelineLayout(vk.device, &desc, nullptr, &vk.pipeline_layout)); + } + + // + // Geometry buffers. + // + { + VkBufferCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + desc.queueFamilyIndexCount = 0; + desc.pQueueFamilyIndices = nullptr; + + desc.size = VERTEX_BUFFER_SIZE; + desc.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + VK_CHECK(vkCreateBuffer(vk.device, &desc, nullptr, &vk.vertex_buffer)); + + desc.size = INDEX_BUFFER_SIZE; + desc.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + VK_CHECK(vkCreateBuffer(vk.device, &desc, nullptr, &vk.index_buffer)); + + VkMemoryRequirements vb_memory_requirements; + vkGetBufferMemoryRequirements(vk.device, vk.vertex_buffer, &vb_memory_requirements); + + VkMemoryRequirements ib_memory_requirements; + vkGetBufferMemoryRequirements(vk.device, vk.index_buffer, &ib_memory_requirements); + + VkDeviceSize mask = ~(ib_memory_requirements.alignment - 1); + VkDeviceSize index_buffer_offset = (vb_memory_requirements.size + ib_memory_requirements.alignment - 1) & mask; + + uint32_t memory_type_bits = vb_memory_requirements.memoryTypeBits & ib_memory_requirements.memoryTypeBits; + uint32_t memory_type = find_memory_type(vk.physical_device, memory_type_bits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + + VkMemoryAllocateInfo alloc_info; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.pNext = nullptr; + alloc_info.allocationSize = index_buffer_offset + ib_memory_requirements.size; + alloc_info.memoryTypeIndex = memory_type; + VK_CHECK(vkAllocateMemory(vk.device, &alloc_info, nullptr, &vk.geometry_buffer_memory)); + + vkBindBufferMemory(vk.device, vk.vertex_buffer, vk.geometry_buffer_memory, 0); + vkBindBufferMemory(vk.device, vk.index_buffer, vk.geometry_buffer_memory, index_buffer_offset); + + void* data; + VK_CHECK(vkMapMemory(vk.device, vk.geometry_buffer_memory, 0, VK_WHOLE_SIZE, 0, &data)); + vk.vertex_buffer_ptr = (byte*)data; + vk.index_buffer_ptr = (byte*)data + index_buffer_offset; + } + + // + // Sync primitives. + // + { + VkSemaphoreCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + + VK_CHECK(vkCreateSemaphore(vk.device, &desc, nullptr, &vk.image_acquired)); + VK_CHECK(vkCreateSemaphore(vk.device, &desc, nullptr, &vk.rendering_finished)); + + VkFenceCreateInfo fence_desc; + fence_desc.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fence_desc.pNext = nullptr; + fence_desc.flags = VK_FENCE_CREATE_SIGNALED_BIT; + VK_CHECK(vkCreateFence(vk.device, &fence_desc, nullptr, &vk.rendering_finished_fence)); + } + + // + // Shader modules. + // + { + auto create_shader_module = [](uint8_t* bytes, int count) { + if (count % 4 != 0) { + ri.Error(ERR_FATAL, "Vulkan error: SPIR-V binary buffer size is not multiple of 4"); + } + VkShaderModuleCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + desc.codeSize = count; + desc.pCode = reinterpret_cast(bytes); + + VkShaderModule module; + VK_CHECK(vkCreateShaderModule(vk.device, &desc, nullptr, &module)); + return module; + }; + + vk.single_texture_vs = create_shader_module(single_texture_vert_spv, single_texture_vert_spv_size); + vk.single_texture_fs = create_shader_module(single_texture_frag_spv, single_texture_frag_spv_size); + vk.multi_texture_vs = create_shader_module(multi_texture_vert_spv, multi_texture_vert_spv_size); + vk.multi_texture_mul_fs = create_shader_module(multi_texture_mul_frag_spv, multi_texture_mul_frag_spv_size); + vk.multi_texture_add_fs = create_shader_module(multi_texture_add_frag_spv, multi_texture_add_frag_spv_size); + } + + // + // Samplers. + // + { + VkSamplerCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + desc.magFilter = VK_FILTER_LINEAR; + desc.minFilter = VK_FILTER_LINEAR; + desc.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + desc.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + desc.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + desc.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + desc.mipLodBias = 0.0f; + desc.anisotropyEnable = VK_TRUE; + desc.maxAnisotropy = 1; + desc.compareEnable = VK_FALSE; + desc.compareOp = VK_COMPARE_OP_ALWAYS; + desc.minLod = 0.0f; + desc.maxLod = 0.0f; + desc.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; + desc.unnormalizedCoordinates = VK_FALSE; + + VK_CHECK(vkCreateSampler(vk.device, &desc, nullptr, &vk.sampler)); + } + + // + // Skybox pipeline. + // + { + Vk_Pipeline_Desc desc; + desc.shader_type = Vk_Shader_Type::single_texture; + desc.state_bits = 0; + desc.face_culling = CT_FRONT_SIDED; + desc.polygon_offset = false; + + vk.skybox_pipeline = create_pipeline(desc); } - return true; } void vk_deinitialize() { diff --git a/src/engine/renderer/vk.h b/src/engine/renderer/vk.h index 46089a6..c6f71fb 100644 --- a/src/engine/renderer/vk.h +++ b/src/engine/renderer/vk.h @@ -50,7 +50,7 @@ struct Vk_Image { VkDescriptorSet descriptor_set; }; -bool vk_initialize(HWND hwnd); +void vk_initialize(HWND hwnd); void vk_deinitialize(); void vk_destroy_resources();